Devise being logged out on post to different route

2019-03-15 06:17发布

问题:

Im having a really strange problem with Devise. I have a route set up that accepts both get and post requests. On a get, it shows the form, on the post, it submits it.

When I send a post XHR to the route, when it gets there it tells me that I am not logged in, and sends me a 401 unauthorized. After that I have to log in, and then I can try again.

I have been trying to figure this out for hours, all I have been able to figure out is that my controller method is not getting called. I put in my own custom auth before filter, and it just confirmed that by the time my rails app gets called, the user is no longer logged in.

Also, if I open up the form, but dont submit it, I can continue on as normal. Somewhere in that XHR it is making devise log me out.

If you have any ideas please help, I have no idea what is going on right now...

Thanks

-Scott

EDIT: Adding relevant pieces of code

routes.rb

match 'projects/:p/filebox' => 'projects#show', :via => ["get","post"], :as => 'project_filebox'

projects_controller.rb

before_filter :authenticate_user! # <--- By the time this gets called, the user is logged out
def show
# ^^^^ Doesnt get called. Logger shows that it recognized route though
logger.debug "-----------projects#show"
logger.debug "Current user logged in:"+user_signed_in?.to_s

form that is being submitted

<form class="upload" action="<%= project_filebox_path(@project) %>?n=7&cType=<%= cType %>&fid=<%= fid %>" method="post" enctype="multipart/form-data">
    <input type="file" name="file" multiple/>
    <button>Upload</button>
    <div>Add / Drag Files To Upload</div>
</form>

Javascript that is uploading the XHR

formDataUpload = function (files, xhr, settings) {
            var formData = new FormData(),
                i;
            $.each(getFormData(settings), function (index, field) {
                formData.append(field.name, field.value);
            });
            for (i = 0; i < files.length; i += 1) {
                formData.append(settings.fieldName, files[i]);
            }
            xhr.send(formData);
        }

If I missed some relevant piece of code let me know

回答1:

There's not that much to go on here other than the JS, but there's a really strong change you're having the problem because the CSRF token isn't being set as part of your request. This has changed in various Rails 3.0.x releases so hard to know for sure without code.

One dead simple test would be to turn off CSRF (e.g. remove protect_from_forgery from ApplicationController). If it works, you have the answer and need to make sure the token gets passed around or you otherwise handle forgery protection.



回答2:

I ran into the same problem when I have two forms in one page, one of them post to an route within then application, the other post to an outside address. John Paul Ashenfelter is right that it has nothing to do with JS.

Like you, I do not want to disable CSRF for the entire site. I ended up disable protect from forgery for the method that is posting to the off site address in the controller:

protect_from_forgery :except => [:some_method]

And in the form that is creating this CSRF problem:

<%= form_for :some_model, authenticity_token: false do%>