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

眉间皱痕 提交于 2019-12-07 09:28:26

问题


I'm following http://railscasts.com/episodes/250-authentication-from-scratch for simple authentication. It works as expected. I have a model in my app 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 within index.html.erb as follows:

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

The destroy.js.erb is as follows, which is called if the object is successfully destroyed.

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

On clicking the delete button, the post object gets deleted properly and the destroy.js.erb is rendered correctly too. But somehow, the user is logged out. Following 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 remove the :remote => true from the delete link, then the user remains logged in. I have log statements in the destroy method for session that are never called in either case, but if ':remote=>true then the session is somehow screwed up. On checking the cookies, I found that the cookie is not destroyed but it does get modified when the destroy method on posts is called. Not sure why this has to happen.


回答1:


Sounds like you are bumping into a rails security feature that is meant to protect against Cross Site Request Forgery. Adding :remote => true causes the request to be submitted via ajax without CSRF security tokens, so rails clobbers the session because it thinks it is a CSRF attack. To get around this you have a few options:

  1. A quick and dirty (and insecure) solution is to turn off the security check for that request. To do this add this line to the top of your controller:

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

  2. A more secure solution is to submit the CSRF token with the AJAX call. I think this will happen automatically if you change your remote link to a button_to. Read more here.

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

  3. You could also cookies to store the current_user rather than the session. The security implications of this will depend on the details of your app.



来源:https://stackoverflow.com/questions/12171230/rails-user-logged-out-after-destroying-an-unrelated-object-with-remote-tru

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!