我有一个在CDN级别缓存的页面,我想要提交表单。
我已关注technique 3 of this post以异步获取csrf元标记,然后在表单中发送这些标记,但是当我尝试时,我在表单提交控制器操作中获取ActionController::InvalidAuthenticityToken
这个。一切似乎都有效,但形式仍被拒绝。
以下是提供csrf信息的操作:
def csrf_meta
respond_to do |format|
format.json do
render json: {
param: request_forgery_protection_token,
token: form_authenticity_token
}
end
end
end
这是JS函数将其附加到<head>
function asyncCsrf() {
window.fetch("/async_info/csrf_meta")
.then(function(response) {
response.json().then(function(json) {
console.log(json);
var meta = document.createElement('meta');
meta.name = "csrf-param";
meta.content = json.param;
document.getElementsByTagName('head')[0].appendChild(meta);
var meta = document.createElement('meta');
meta.name = "csrf-token";
meta.content = json.token;
document.getElementsByTagName('head')[0].appendChild(meta);
});
}).catch(function(err) {
console.log(err);
});
}
这是JS将真实性标记添加到表单中:
var authToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
// later:
<input type="hidden" name="authenticity_token" value="'+authToken+'">
一切似乎都存在。该令牌与表单一起传递,但ActionController::InvalidAuthenticityToken
仍然存在。
答案 0 :(得分:0)
我解决了这个问题:由于某种原因,fetch()
API返回了错误的会话。好老式的XMLHttpRequest()
有效。我想可能标题不会自动包含在fetch
调用中,而是XMLHttpRequest
。一旦我对此感到沮丧,我将独立调查。