Rails 3.1 - CSRF 被忽略?

发布于 2024-12-02 08:56:44 字数 538 浏览 2 评论 0原文

这是我的问题,

我有一个 Rails 3.1 应用程序,我正在尝试发出 ajax 请求,但我收到警告消息 “警告:无法验证 CSRF 令牌真实性”...

在我的布局内我有辅助方法 "csrf_method_tag",并且添加了以下 javascript 代码(不知道是否真的需要):

$.ajaxSetup({
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
  }
});

我的 Gemfile 包含 gem jquery-rails (>= 1.0.12) 并且我需要 jquery & jquery-ujs 位于我的 application.js 的顶部。

即使如此,该消息仍然出现。我是不是忘记了什么?

谢谢你的帮助。

here my problem,

I've got a rails 3.1 app and I'm trying to make an ajax request but I get the warning message "WARNING: Can't verify CSRF token authenticity"…

Inside my layout I've got the helper method "csrf_method_tag", and I add the following javascript code (don't know if it's really required or not):

$.ajaxSetup({
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
  }
});

My Gemfile contains the gem jquery-rails (>= 1.0.12) and I require jquery & jquery-ujs at the top of my application.js.

Even with that, the message still appears. Did i forget something?

Thanks for you help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

把时间冻结 2024-12-09 08:56:44

我也遇到了同样的麻烦。我试图捕获一个 javascript 事件(you_tube 播放器已完成)并 Ajax 返回到我的服务器来让我知道。我得到:

WARNING: Can't verify CSRF token authenticity

每当 jQuery ajax 调用到达我的服务器时。我在上面添加了您的代码修复

$.ajaxSetup({
    beforeSend: function(xhr) {
        xhr.setRequestHeader('X-CSRF-Token',
                             $('meta[name="csrf-token"]').attr('content'));
    }
});

,它工作正常。我认为唯一的区别在于我的布局,

<%= csrf_meta_tags %>

而不是您在原始帖子中提到的 csrf_method_tag。
所以感谢您的修复,它在原始帖子中。

I had this exact same trouble. I was trying to catch a javascript event (you_tube player completed) and Ajax back to my server to let me know. I was getting:

WARNING: Can't verify CSRF token authenticity

whenever the jQuery ajax call hit my server. I added your code fix above

$.ajaxSetup({
    beforeSend: function(xhr) {
        xhr.setRequestHeader('X-CSRF-Token',
                             $('meta[name="csrf-token"]').attr('content'));
    }
});

and it works fine. I think the only difference is in my layout I have

<%= csrf_meta_tags %>

and not csrf_method_tag as you mentioned in your original post.
So thank you for the fix, it was in the original post.

破晓 2024-12-09 08:56:44

对我来说,在没有表单的情况下工作时,最有效的方法是将 <%= form_authenticity_token %> 的结果包含在 ajax 数据负载中。 then call the $.ajax with submitdata中建议的操作

<input id="tokentag" type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />

所以我做了类似于 tehprofessor 在 html: then in the javascript:

tokentag = $('#tokentag').val()
submitdata = { "authenticity_token": tokentag, ...+whatever else you need to include+...}

What's worked for me - when working without forms - is to include the result of <%= form_authenticity_token %> in the ajax data payload. So I do something like what was suggested by tehprofessor in the html:

<input id="tokentag" type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />

then in the javascript:

tokentag = $('#tokentag').val()
submitdata = { "authenticity_token": tokentag, ...+whatever else you need to include+...}

then call the $.ajax with submitdata.

阳光下慵懒的猫 2024-12-09 08:56:44

您的代码中可能甚至不需要这个。默认情况下,jquery-rails gem 自动在所有 Ajax 请求上设置 CSRF 令牌。

You probably don't even need this in your code. The jquery-rails gem automatically sets the CSRF token on all Ajax requests by default.

仅此而已 2024-12-09 08:56:44

只需直接在 AJAX 调用中执行此操作即可正常工作!

  $.ajax({
            type: //method,
            beforeSend: function(xhr){
                xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
            },
            url: //parameter,
            dataType: 'html',
            success: function(data, textStatus, jqXHR) {
               // some code
            }
  });

Just do it directly on your AJAX call and it will work right!

  $.ajax({
            type: //method,
            beforeSend: function(xhr){
                xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
            },
            url: //parameter,
            dataType: 'html',
            success: function(data, textStatus, jqXHR) {
               // some code
            }
  });
娇俏 2024-12-09 08:56:44

您是否尝试过使用带有真实性令牌的隐藏表单元素?

<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token>" />

我遇到了同样的错误,这解决了它。这是因为我没有使用内置的表单助手......

Have you tried using a hidden form element with authenticity token?

<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token>" />

I was having the same error, and that resolved it. It was because I wasn't using the built in form helpers...

吝吻 2024-12-09 08:56:44

原因之一可能是您在加载文档之前进行了 AJAX 调用,因此 JQuery 无法获取 CSRF 令牌。

One reason may be that you make AJAX call before document loaded, so JQuery can't get CSRF token.

输什么也不输骨气 2024-12-09 08:56:44

问题是您需要在 Ajax POST 请求后获取新令牌,因为一旦使用令牌,它就会失效。下面是执行此操作的代码:

在 Rails 中,每当发送 POST 回复时,将这些参数添加到响应中:

def someMethod:
    result[:csrfParam] = request_forgery_protection_token
    result[:csrfToken] = form_authenticity_token
    render :json => result
end

现在在 JS 端,在每个 POST 方法的成功函数中,您可以调用此函数:

var setCsrfToken = function(param, token) {
    if(param == null || token == null) {
        console.error("New CSRF param/token not present");
    }
    $("input[name='" + param + "']").val(token);
}

像这样:

setCsrfToken(result["csrfParam"], result["csrfToken"]);

此函数将重置所有 POST 表单中的所有authenticity_token 参数,以便下一个请求具有有效的令牌。您需要确保在每次 POST 调用中都发生这种情况,否则您将继续面临此问题。

此外,CSRF 并不是为了防止点击劫持,它完全是一种单独的攻击,其中另一个网站可以让用户单击链接,从而通过用户会话在您的网站上执行操作。

The problem is that you need to fetch a new token after an Ajax POST request because once a token is used it gets invalidated. Here is the code to do this:

In rails whenever a POST reply is sent add these parameters to the response:

def someMethod:
    result[:csrfParam] = request_forgery_protection_token
    result[:csrfToken] = form_authenticity_token
    render :json => result
end

Now on the JS side, in the success function of every POST method you can call this function:

var setCsrfToken = function(param, token) {
    if(param == null || token == null) {
        console.error("New CSRF param/token not present");
    }
    $("input[name='" + param + "']").val(token);
}

like this:

setCsrfToken(result["csrfParam"], result["csrfToken"]);

This function will reset all authenticity_token params in all POST forms so that the next request has a valid token. You need to make sure this happens in every POST call, otherwise you'll continue facing this problem.

Also, CSRF is not for preventing clickjacking, it's a separate attack altogether, where another website can make a user click a link that executes an action on your website with the user's session.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文