2012-08-29 22 views
4

我正在關注http://railscasts.com/episodes/250-authentication-from-scratch以進行簡單身份驗證。它按預期工作。我在我的應用程序的模型具有以下partialRails:用戶通過以下方式銷燬不相關對象後註銷用戶:remote => true

<%= 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 

任何線索爲什麼會有這種行爲?

而且,如果我從delete鏈接刪除:remote => true,則用戶保持登錄狀態。我已經登錄到destroy方法session陳述,從來沒有在任何一種情況下調用,但如果':remote=>true那麼會話是莫名其妙搞砸了。在檢查cookie時,我發現cookie不會被破壞,但當調用posts上的destroy方法時,它會被修改。不知道爲什麼會發生這種情況。

回答

4

聽起來就像您正在碰撞安全防護功能,以防止Cross Site Request Forgery。添加:remote => true會導致請求通過沒有CSRF安全性令牌的ajax提交,因此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. 你也餅乾存儲CURRENT_USER而不是會話。這會影響安全性,這取決於你的應用程序的細節。

+0

Rails 3.0.9中未定義'link_to_remote'方法嗎?我試着做'<%= link_to_remote'刪除',:url => url_for(post),:method =>:delete,:confirm =>'你確定嗎? %>'。 – brayne

+0

選項#1和3不適用於當前情況,但很好理解!並且,'button_to'也很好用。 – brayne

+0

似乎'link_to_remote'已折舊。我從我的答案中刪除了它。 – Matthew