【问题标题】:Rails authenticity token (CSRF) provided but being refusedRails 真实性令牌 (CSRF) 已提供但被拒绝
【发布时间】:2015-09-04 21:58:19
【问题描述】:

我正在从我的 rails 站点向自身发送 AJAX 请求(从 javascript 到控制器)。除非我提供真实性令牌,否则 Rails 拒绝允许 POST,因此我使用

添加了一个
<%= csrf_meta_tags %> 

var AUTH_TOKEN = "<%=j form_authenticity_token %>"

一切都很好。然而,一位新客户最近安装了访问我的网站并首先触发 AJAX 的插件。但是对于这个客户——尽管提供了真实性令牌,但仍被拒绝(我检查了日志。)

我意识到我并没有提供很多线索,但是什么会导致真实性令牌在一种情况下被接受而在另一种情况下被拒绝?更广泛地说,authentity_token 是如何生成的——每次加载页面时都会生成一个新的?

【问题讨论】:

    标签: ruby-on-rails ajax csrf


    【解决方案1】:

    Rails 将加密随机 CSRF 令牌分配给用户会话。

    服务器会将为authenticity_token 参数提交的值与与用户会话关联的值进行比较。

    您特别需要注意的一件事是,如果您使用片段缓存(通过缓存视图块来加速渲染),您需要确保您的 &lt;%= csrf_meta_tags %&gt; 不会因为一个陈旧的 csrf 元标记而被缓存会导致与session中存储的token不匹配。

    使用 ajax 发布时,您需要使用 X-CSRF-Token 标头转发 CSRF 令牌。

    var promise = $.ajax({ 
        url: '/example',
        type: 'POST',
        beforeSend: function(xhr) { 
            xhr.setRequestHeader('X-CSRF-Token', 
            $('meta[name="csrf-token"]').attr('content')) 
        },
        data: 'someData=' + someData
    });
    

    【讨论】:

    • 感谢 maxcal——这非常有帮助,尤其是关于片段缓存的部分(我一直想知道是否发生了类似的事情。)
    • @max 我不确定是否需要附加 csrf,因为它是由 rails jquery_ujs.js 处理的,对吗? CSRFProtection: function(xhr) { var token = $('meta[name="csrf-token"]').attr('content'); if (token) xhr.setRequestHeader('X-CSRF-Token', token); },
    • 抱歉回复晚了。我不完全确定,但我相信 jQuery UJS 会在您对表单和链接使用 remote: true 属性时处理 CRS,但它不会猴子补丁 jQuery 来改变 $.ajax 的行为 - 所以如果您正在执行 ajax 调用您自己需要手动将令牌附加到请求中。
    猜你喜欢
    • 2012-07-29
    • 2021-12-10
    • 2014-06-16
    • 2017-07-15
    • 2015-07-24
    • 2012-05-08
    • 2015-12-29
    • 2023-03-26
    • 2016-09-17
    相关资源
    最近更新 更多