Rails, Devise authentication, CSRF issue(Rails,设计认证,CSRF 问题)
问题描述
我正在使用 Rails 做一个单页应用程序.登录和注销时,使用 ajax 调用 Devise 控制器.我遇到的问题是,当我 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 令牌有关(尽管它不应该 afaik),并且由于它是单页,旧的 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:
- 登录
 - 退出
 - 登录(成功 201.但是在服务器日志中打印 
WARNING: Can't verify CSRF tokenauthity) - 后续 ajax 请求失败 401 unauthorized
 - 刷新网站(此时页眉中的CSRF变为其他内容)
 - 我可以登录,它可以正常工作,直到我尝试退出并重新登录.
 
非常感谢任何线索!让我知道是否可以添加更多详细信息.
Any clues very much appreciated! Let me know if I can add any more details.
推荐答案
Jimbo 出色地解释了您遇到的问题背后的原因".您可以采取两种方法来解决此问题:
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:
(根据 Jimbo 的建议)重写 Devise::SessionsController 以返回新的 csrf-token:
(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 请求创建一个成功处理程序(可能需要根据您的设置进行一些调整,例如 GET 与 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"));
});
更简单地说,如果它适合您的应用程序,您可以简单地覆盖 Devise::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 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Rails,设计认证,CSRF 问题
				
        
 
            
        - 是否可以将标志传递给 Gulp 以使其以不同的方式 2022-01-01
 - 我不能使用 json 使用 react 向我的 web api 发出 Post 请求 2022-01-01
 - 如何向 ipc 渲染器发送添加回调 2022-01-01
 - 为什么悬停在委托事件处理程序中不起作用? 2022-01-01
 - 为什么我的页面无法在 Github 上加载? 2022-01-01
 - 使用 iframe URL 的 jQuery UI 对话框 2022-01-01
 - 如何调试 CSS/Javascript 悬停问题 2022-01-01
 - 从原点悬停时触发 translateY() 2022-01-01
 - 在不使用循环的情况下查找数字数组中的一项 2022-01-01
 - 如何显示带有换行符的文本标签? 2022-01-01
 
						
						
						
						
						
				
				
				
				