我確實遇到了這個問題,在這種情況下,我不想跳過verify_authenticity_token
過濾器,也不會更改爲protect_from_forgery with: :null_session
。無法驗證CSRF令牌的真實性Rails 4 Ajax即使設置了標頭時也是如此
在我的請求的方法,我設置的文件頭和CSRF令牌如下:
var token = document.querySelector("meta[name='csrf-token']").content;
xhr.setRequestHeader("X-CSRF-Token", token);
而且在我的控制器中插入一個斷點,像這樣:
def verify_authenticity_token
binding.pry
super
end
我已驗證標頭設置爲:
[1] pry(#<MyController>)> request.headers
=> #<ActionDispatch::Http::Headers:0x007fb227cbf490
@env=
{"CONTENT_LENGTH"=>"202",
.
.
.
# omitted headers
.
.
.
"HTTP_X_CSRF_TOKEN"=>"the-correct-token-from-meta-tag",
.
.
.
}
我也試過將標記作爲參數傳遞給密鑰authenticity_token
(與Rails表單一樣),並將X-CSRF-Param
標記設置爲匹配(從meta[name="csrf-param"]
)。
但我仍然得到:
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 14638ms
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken
沒有人見過這個?有什麼想法可能會導致這種情況?
在此先感謝!
編輯:
繼marflar的答案的意見討論,它看起來像當請求時令牌已過期(通過比較form_authenticity_token
測試)。這使我更加困惑,因爲在下一個請求進入時,<%= csrf_meta_tags %>
中設置的令牌已過期。有什麼想法?
EDIT2:按照下面marflar的建議下,我增加了以下after_filter
到我的應用程序控制器:
def set_csrf_headers
response.headers['X-CSRF-Param'] = request_forgery_protection_token.to_s
response.headers['X-CSRF-Token'] = form_authenticity_token
end
而且我在我的請求方法更新xhr.onload
如下:
namespace.request = = function (type, url, opts, callback) {
// code omitted
xhr.onload = function() {
setCSRFHeaders(xhr);
var res = {data: JSON.parse(xhr.response), status: xhr.status};
return callback.call(xhr, null, res);
};
// code omitted
}
function setCSRFHeaders (xhr) {
var csrf_param = xhr.getResponseHeader('X-CSRF-Param');
var csrf_token = xhr.getResponseHeader('X-CSRF-Token');
if (csrf_param) {
document.querySelector("meta[name='csrf-param']").content = csrf_param;
}
if (csrf_token) {
document.querySelector("meta[name='csrf-token']").content = csrf_token;
}
}
我驗證了響應標頭,然後元標記得到正確重置,但是,到下一個請求進入時,這個新的令牌會再次過期。思考?
我不確定我是否理解你在'HTML'中的含義 - 你能給我一個例子嗎? – mattmattmatt 2014-10-18 21:35:56
@fancycoder我更新了我的答案,我不知道你是否可能會使用陳舊的標記 – stephenmurdoch 2014-10-18 21:46:26
我剛剛檢查過,你說的是一個陳舊的標記,這不幸讓我更加困惑。具有CSRF數據的元標記在初始頁面加載時設置,這時它們與'form_authenticity_token'匹配,但在第一個Ajax請求發出時該標記已過時。因此,將它們設置爲HTML還是作爲標題並不重要,因爲這會同時發生,因此會在下一個請求發生之前遇到與令牌過期相同的問題。感謝您的幫助至今 - 這裏的任何想法? – mattmattmatt 2014-10-18 22:02:08