javascript – 即使设置了标头,也无法验证CSRF令牌真实性Rails 4 Ajax

前端之家收集整理的这篇文章主要介绍了javascript – 即使设置了标头,也无法验证CSRF令牌真实性Rails 4 Ajax前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我真的遇到了这个问题,在这个例子中,我既不想跳过verify_authenticity_token过滤器,也不想用:: null_session更改为protect_from_forgery.

在我的请求方法中,我使用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添加到我的app控制器:

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

我验证了响应标头,然后元标记正在被正确重置,但是,当下一个请求进入时,这个新标记再次过期.思考?

解决方法

我也有同样的问题.我检查了Rails源代码并接下来得出结论:

> authenticity_token本身没有过期,所以在每次向服务器发出ajax请求后都不需要更新它
>不需要发送params [:authenticity_token]和header [‘x-csrf-token’],只需其中一个,rails将首先检查params,而不是header
>在页面刷新时,authenticity_token会有所不同,但没关系,因为每次使用一次填充生成它并且真正的csrf令牌(在服务器上)与时间无关
>会话中保存的真实csrf令牌[:_ csrf_token]

你可以看到令牌保持在会话中我的问题是我的会话在24小时后过期(可能是用户页面上停留一天没有刷新)

如果用户通过cookie或其他令牌参数登录,则无论如何他都会获得新会话,并且会生成新的CSRF令牌,并且任何具有旧authenticity_token的请求都将无效.

因此,主要问题是会话,它已过期或重置.

原文链接:https://www.f2er.com/ajax/156617.html

猜你在找的Ajax相关文章