Rails的,设计验证,CSRF问题 [英] Rails, Devise authentication, CSRF issue
问题描述
我在做什么使用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:
- 登录
- 退出
- 登录(成功201。然而版画
警告:无法验证CSRF令牌真实性
服务器日志) - 在随后的AJAX请求失败401未授权
- 刷新的网站(在这一点上,CSRF在页眉更改为别的东西)
- 我可以登录,它的工作原理,直到我尝试退出并重新连接。
- Sign in
- Sign out
- Sign in (successful 201. However prints
WARNING: Can't verify CSRF token authenticity
in server logs) - Subsequent ajax request fails 401 unauthorised
- Refresh the website (at this point, CSRF in the page header changes to something else)
- 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:
-
(所推荐的神保)重写制定:: SessionsController回报新CSRF令牌:
(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屋!