Rails:用户使用以下命令销毁不相关的对象后退出:remote =>真正

时间:2012-08-29 05:08:10

标签: ruby-on-rails ruby ajax authentication railscasts

我正在关注http://railscasts.com/episodes/250-authentication-from-scratch进行简单身份验证。它按预期工作。我的应用中有一个模型,其中包含以下partial

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

index.html.erb内调用如下:

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

destroy.js.erb如下所示,如果对象被成功销毁,则会调用它。

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

点击delete按钮后,post对象会被正确删除,destroy.js.erb也会正确呈现。但不知何故,用户退出了。以下是我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

为什么会出现这种行为?

并且,如果我从:remote => true链接中删除delete,则用户仍然会登录。我在destroy session方法中有日志语句在任何一种情况下从未调用,但如果':remote=>true那么会话就会以某种方式搞砸了。在检查cookie时,我发现cookie没有被销毁,但是当调用destroy上的posts方法时,它会被修改。不知道为什么会这样。

1 个答案:

答案 0 :(得分:4)

听起来你正在碰到一个旨在防范Cross Site Request Forgery的铁路安全功能。添加:remote => true会导致请求通过ajax提交而没有CSRF安全令牌,因此rails会破坏会话,因为它认为这是CSRF攻击。要解决这个问题,您可以选择以下几种方法:

  1. 快速而肮脏(且不安全)的解决方案是关闭该请求的安全检查。为此,请将此行添加到控制器的顶部:

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

  2. 更安全的解决方案是使用AJAX调用提交CSRF令牌。我认为如果您将远程链接更改为button_to,这将自动发生。阅读更多here

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

  3. 您还可以使用Cookie来存储current_user而不是会话。这对安全性的影响取决于您的应用程序的详细信息。