Rails的,设计验证,CSRF问题 [英] Rails, Devise authentication, CSRF issue

查看:174
本文介绍了Rails的,设计验证,CSRF问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做什么使用Rails单张页的应用程序。当进出设计控制器签约使用AJAX调用。我得到的问题是,当我1)2号)注销然后再次登录不起作用。

I'm doing a singe-page application using Rails. When signing in and out Devise controllers are invoked using ajax. The problem I'm getting is that when I 1) sign in 2) sign out then signing in again doesn't work.

我认为这是关系到CSRF令牌,该令牌被复位,当我退出(尽管它不应该据我所知)并且由于它是单页,老CSRF令牌被发送XHR请求从而复位会话。

I think it's related to CSRF token which gets reset when I sign out (though it shouldn't afaik) and since it's single page, the old CSRF token is being sent in xhr request thus resetting the session.

要更具体,这是工作流程:

To be more concrete this is the workflow:

  1. 登录
  2. 退出
  3. 登录(成功201。然而版画警告:无法验证CSRF令牌真实性服务器日志)
  4. 在随后的AJAX请求失败401未授权
  5. 刷新的网站(在这一点上,CSRF在页眉更改为别的东西)
  6. 我可以登录,它的工作原理,直到我尝试退出并重新连接。
  1. Sign in
  2. Sign out
  3. Sign in (successful 201. However prints WARNING: Can't verify CSRF token authenticity in server logs)
  4. Subsequent ajax request fails 401 unauthorised
  5. Refresh the website (at this point, CSRF in the page header changes to something else)
  6. I can sign in, it works, until I try to sign out and in again.

任何线索非常AP preciated!让我知道如果我可以添加更多的细节。

Any clues very much appreciated! Let me know if I can add any more details.

推荐答案

神保做一个真棒的工作,解释了为什么的问题背后的你正在运行之中。有两种方法可以采取以解决问题:

Jimbo did an awesome job explaining the "why" behind the issue you're running into. There are two approaches you can take to resolve the issue:

  1. (所推荐的神保)重写制定:: SessionsController回报新CSRF令牌:

  1. (As recommended by Jimbo) Override Devise::SessionsController to return the new csrf-token:

class SessionsController < Devise::SessionsController
  def destroy # Assumes only JSON requests
    signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
    render :json => {
        'csrfParam' => request_forgery_protection_token,
        'csrfToken' => form_authenticity_token
    }
  end
end

和创建一个成功的处理程序在客户端上你的SIGN_OUT请求(可能需要根据你的设置一些调整,例如获得与DELETE):

And create a success handler for your sign_out request on the client side (likely needs some tweaks based on your setup, e.g. GET vs DELETE):

signOut: function() {
  var params = {
    dataType: "json",
    type: "GET",
    url: this.urlRoot + "/sign_out.json"
  };
  var self = this;
  return $.ajax(params).done(function(data) {
    self.set("csrf-token", data.csrfToken);
    self.unset("user");
  });
}

这也假设你包括CSRF令牌自动与像这样所有的Ajax请求:

This also assumes you're including the CSRF token automatically with all AJAX requests with something like this:

$(document).ajaxSend(function (e, xhr, options) {
  xhr.setRequestHeader("X-CSRF-Token", MyApp.session.get("csrf-token"));
});

  • 更​​简单地说,如果是适合您的应用程序,你可以简单地覆盖制定:: SessionsController 并覆盖令牌检查与 skip_before_filter:verify_authenticity_token

  • Much more simply, if it is appropriate for your application, you can simply override the Devise::SessionsController and override the token check with skip_before_filter :verify_authenticity_token.

    这篇关于Rails的,设计验证,CSRF问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆