我正在使用Rails做一个单页应用程序。登录和注销时,使用ajax调用Devise控制器。我遇到的问题是当我1)登录2)退出然后再次登录时不起作用。
我认为这与CSRF令牌有关,该令牌在我退出时会重置(尽管它不应该出现),并且由于它是单页的,因此在xhr请求中发送了旧的CSRF令牌,从而重置了会话。
更具体地说,这是工作流程:
WARNING: Can't verify CSRF token authenticity
任何线索非常感谢!让我知道是否可以添加更多详细信息。
Jimbo做得很出色,解释了您遇到的问题背后的“原因”。您可以采用两种方法来解决此问题:
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 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"); }); }
这还假定您将在所有AJAX请求中自动包含CSRF令牌,如下所示:
$(document).ajaxSend(function (e, xhr, options) { xhr.setRequestHeader("X-CSRF-Token", MyApp.session.get("csrf-token")); });
Devise::SessionsController
skip_before_filter :verify_authenticity_token