gpt4 book ai didi

javascript - 即使设置了 header ,也无法验证 CSRF token 真实性 Rails 4 Ajax

转载 作者:数据小太阳 更新时间:2023-10-29 04:47:47 33 4
gpt4 key购买 nike

我真的遇到了麻烦,在这种情况下,我不想跳过 verify_authenticity_token过滤器,也不更改为 protect_from_forgery with: :null_session .

在我的请求方法中,我使用 csrf token 设置 header ,如下所示:

var token = document.querySelector("meta[name='csrf-token']").content;
xhr.setRequestHeader("X-CSRF-Token", token);

然后像这样在我的 Controller 中插入一个断点:

def verify_authenticity_token
binding.pry
super
end

我已验证 header 已设置:

[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",
.
.
.
}

我还尝试将 token 作为参数传递给 key 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 的回答的评论中进行讨论后,看起来 token 在发出请求时已过期(通过与 form_authenticity_token 进行比较测试)。这让我更加困惑,因为 token 设置在 <%= csrf_meta_tags %> 中下一个请求到来时已过期。有什么想法吗?

EDIT2:按照下面 marflar 的建议,我添加了以下内容 after_filter到我的应用程序 Controller :

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;
}
}

我验证了响应 header ,然后元标记被正确重置,但是,在下一个请求到来时,这个新 token 再次过期。想法?

最佳答案

我也遇到了同样的问题。我检查了 Rails 源代码并得出以下结论:

  • authenticity_token 不会自行过期,因此无需在每次向服务器发出 ajax 请求后更新它
  • 不需要同时发送 params[:authenticity_token]header['x-csrf-token'],只需要其中一个,rails 会检查 params 先,然后是 header
  • 在页面刷新时,authenticity_token 会有所不同,但这没关系,因为它每次都是用一个时间段生成的,而真正的 csrf token (在服务器上)是时间独立的
  • 保存在 session[:_csrf_token] 中的真实 csrf token

如您所见, token 保留在 session 中,我的问题是我的 session 在 24 小时后过期(可能用户在页面上停留了一天而没有刷新)

如果用户通过 cookie 或其他一些 token 参数登录,无论如何他都会获得新 session ,并且会生成新的 CSRF token ,并且任何使用旧 authenticity_token 的请求都将无效。

因此,主要问题在于 session ,它已过期或已重置。

关于javascript - 即使设置了 header ,也无法验证 CSRF token 真实性 Rails 4 Ajax,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26444727/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com