My Rails應用程序採用面向公衆的形式,通過AJAX將用戶輸入作爲字符串化的JSON傳遞給控制器。該表單專爲脫機使用而設計,因此每次訪問除第一頁以外的表單頁面都是通過瀏覽器緩存(使用緩存清單)提供的。我有一個問題,表單提交返回一個422 unprocessable entity
錯誤,除非在導航到表單頁面之前瀏覽器歷史記錄已被清除......也就是說用戶只能進行一個表單提交,所有後續提交內容爲422
,除非他們清除歷史並返回到表單來刷新緩存。不幸的是,這不會飛。Rails/AJAX緩存表單提交 - 422無法處理的實體
我對Rails的安全性並沒有太大的經驗,但我的印象是這與CSRF保護有關,而且對於除第一個表單頁之外的任何訪問,一個陳舊的CSRF標記正在通過。
我的AJAX請求看起來就像這樣:
$.ajax({
url: "post/submission",
type: "POST",
dataType: "json",
beforeSend: function(xhr) {xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"))},
data: {"post" : postParameter},
success: function(response){
window.location = '/post/approval';
}
});
目前,佈局頁包含<%= csrf_meta_tags %>
,我必須在應用程序控制器標準protect_from_forgery with: :exception
。
需要注意這種形式的最終結構件是,雖然表單本身是面向公衆的,它需要用戶登錄後,點擊提交按鈕 - 所以提交將沒有有效的登錄成功。
有沒有一種安全的方法可以解決這個問題?我相信這一點不言而喻,但我不能讓我的用戶在每次提交後清除歷史記錄並重新緩存表單。
如果您想要保持CSRF保護,則必須在呈現表單時重新生成令牌。 '<%= hidden_field_tag:authenticity_token,form_authenticity_token%>'這樣做。從緩存中顯示頁面時的ajax調用會執行。查看更多[here](http://stackoverflow.com/questions/8503447/rails-how-to-add-csrf-protection-to-forms-created-in-javascript)和[here](http:// stackoverflow .COM /問題/ 829046 /怎麼辦 - 我 - 檢測 - 如果-A-用戶已經-了到一個頁面,使用最後退按鈕)。 –
嗯......我應該提到的另一件事是,表單不是以標準的Rails方式與表單助手等構建的。事實上,表單並非HTML表單中的一種表單 - 在提交時,用戶輸入被編譯成一個JSON字符串,然後通過AJAX將其解析出來並插入到數據庫中...所以這裏沒有一個地方可以放置一個'hidden_field_tag'。我認爲在你加入的第二個鏈接中可能有一些很好的解決方案 - 我會測試它們,並讓你知道我是否可以得到任何東西。感謝您的時間。 – skwidbreth
當然,您只需將'form_authenticity_token'的結果傳遞給您的前端,而不管它是作爲模板呈現的一部分完成還是通過ajax調用傳輸。從那裏你可以將它包含到你的POST負載中。 –