在 Rails Devise 中进行删除提取时,过滤器链因 :verify_signed_out_user 呈现或重定向错误而停止

mat*_*cci 5 ruby-on-rails devise reactjs

我使用 React 作为前端,rails/devise 作为后端/auth。登录和注册新用户工作得很好,但是当我尝试使用 devise 创建的 /users/sign_out 路由(如 wiki 概述注销时,我收到错误:

Filter chain halted as :verify_signed_out_user rendered or redirected
Run Code Online (Sandbox Code Playgroud)

我的 fetch 调用如下:

const logout = (event) => {
    event.preventDefault();
    fetch('http://localhost:3000/users/sign_out',{
        method: 'DELETE',
        headers: {
            'Content-type': 'application/json',
            'Accept': 'application/json'
        },
        body: JSON.stringify({ 
            user: JSON.parse(localStorage.getItem('user'))
        })
    })
    .then(res => res.json())
    .then(resp => console.log(resp))
}
Run Code Online (Sandbox Code Playgroud)

我也对我的应用程序控制器进行了以下更改。不完全确定这是否是问题的一部分:

class ApplicationController < ActionController::API
    include ActionController::MimeResponds
    respond_to :json, :html

    before_action :configure_permitted_parameters, if: :devise_controller?
    before_action :authenticate_user!

    protected

    def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:login, keys: [:username, :email, :password])
        devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :email, :password])
        devise_parameter_sanitizer.permit(:account_update, keys: [:username])
    end

end
Run Code Online (Sandbox Code Playgroud)

我尝试过使用

skip_before_action :verify_signed_out_user 
Run Code Online (Sandbox Code Playgroud)

在我的应用程序控制器中,但它引发了该方法未定义的错误。

ArgumentError (Before process_action callback :verify_signed_out_user has not been defined):
Run Code Online (Sandbox Code Playgroud)

感谢任何和所有的帮助。谢谢你!

小智 2

我认为问题是您没有随请求发送用户身份验证令牌标头。您只是将用户作为正文参数发送。通常在逻辑中我们设置 Header 来Authorization: Bearer xyz对用户进行身份验证。

当您希望用户注销时,您必须发送身份验证令牌,以便设备可以识别用户并将用户注销。

因此,当 devise 尝试运行verify_signed_out_user-> 由于用户未登录(您的情况下没有身份验证令牌)时,就会出现此问题。

并且verify_signed_out_user不是像 那样的全局方法authenticate_user!,所以你不能before_action :verify_signed_out_user像我们通常调用的那样调用before_action :authenticate_user!来验证用户。