Rails: User logged out after destroying an unrelated object with: remote => true

I follow http://railscasts.com/episodes/250-authentication-from-scratch for simple authentication. It works as expected. I have a model in my application with the following partial :

 <%= content_tag_for(:li, post) do %> <%= link_to 'Delete', post, :confirm => 'Are you sure?', :method => :delete, :remote => true %> <% end %> 

It is called inside index.html.erb as follows:

 <%= render :partial => @posts.reverse %> 

destroy.js.erb looks like this, which is called if the object is successfully destroyed.

 $('#<%= dom_id(@post) %>').css('background', 'red'); $('#<%= dom_id(@post) %>').hide(); 

When you click the delete button, the post object is deleted properly, and destroy.js.erb also displays correctly. But for some reason, the user logged out. Below is the code for my posts_controller.rb :

  def destroy logger.error 'in destroy' @post = Job.find(params[:id]) @post.destroy respond_to do |format| format.html { redirect_to(posts_url) } format.xml { head :ok } format.js end end 

Any clues why this behavior?

And, if I delete :remote => true from the delete link, then the user will remain in the system. I have log statements in the destroy method for session that are never called in both cases, but if ' :remote=>true , then the session is somehow messy. When checking cookies, I found that the cookie is not destroyed, but it changes when the destroy method on posts called. Not sure why this should happen.

+4
source share
1 answer

It looks like you are bumping into a rail safety feature designed to protect against firewall request routine . Addendum :remote => true forces the request to be sent via ajax without CSRF security tokens, so the rails capture the session because it considers this to be a CSRF attack. To get around this, you have several options:

  • A quick and dirty (and unsafe) solution is to disable the security check for this request. To do this, add this line to the top of your controller:

    skip_before_filter :verify_authenticity_token, :only => [:destroy]

  • A safer solution is to send the CSRF token using an AJAX call. I think this will happen automatically if you change your remote link to button_to . More details here .

    <%= button_to 'Delete', post, :confirm => 'Are you sure?', :method => :delete, :remote => true %>

  • You can also use cookies to store current_user, not a session. The security implications for this will depend on the details of your application.

+4
source

All Articles