问题
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:
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]
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 abutton_to
. Read more here.<%= button_to 'Delete', post, :confirm => 'Are you sure?', :method => :delete, :remote => true %>
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