注销时出错:未定义的方法 'invalidate_token'

Error on Logout: undefined method 'invalidate_token'

我正在 Rails 5 API 上构建身份验证,但我在注销部分遇到了问题。我正在点击 /logout 路线并收到 500 错误读数 NoMethodError: undefined method 'invalidate_token' for nil:NilClass>,然后它引用了我的 sessions_controller。我的 sessions_controller 引用了用户模型中声明的注销方法中的 invalidate_token 方法,我很困惑为什么当我在模型中定义错误时控制器中未定义错误。

sessions_controller:

class SessionsController < ApiController
  skip_before_action :require_login, only: [:create], raise: false

  def create
    if (user = User.validate_login(params[:username], params[:password]))
      allow_token_to_be_used_only_once_for(user)
      send_token_for_valid_login_of(user)
    else
      render_unauthorized('Error creating the session with provided credentials')
    end
  end

  def destroy
    logout
    head :ok
  end

  private

  def send_token_for_valid_login_of(user)
    render json: { token: user.auth_token }
  end

  def allow_token_to_be_used_only_once_for(user)
    user.regenerate_auth_token
  end

  def logout
    @current_user.invalidate_token
  end
end

用户模型

class User < ApplicationRecord
  # validate unique username and email
  validates_uniqueness_of :username, :email
  has_secure_password
  has_secure_token :auth_token

  # clear token value, used to logout
  def invalidate_token
    self.update_columns(auth_token: nil)
  end

  def self.validate_login(username, password)
    user = User.find_by(username: username)
    if user && user.authenticate(password)
      user
    end
  end
end

API 控制器:

class ApiController < ApplicationController
  def require_login
    authenticate_token || render_unauthorized('Access Denied: Unauthorized Access')
  end

  def current_user
    @current_user ||= authenticate_token
  end

  protected

  def render_unauthorized(message)
    errors = { errors: [detail: message] }
    render json: errors, status: :unauthorized
  end

  private

  def authenticate_token
    authenticate_with_http_token do |token|
      User.find_by(auth_token: token)
    end
  end
end

理想情况下,这应该通过注销方法,以便它可以呈现 200 并实际上使登录的用户令牌无效。

这是因为您的current_user是nil.You,在请求注销时必须发送auth_token。使用此 auth_token 您必须获取用户,以便您可以更新该用户 -- nil auth_token。如果找不到用户,那么您必须处理这种情况下的异常,因为您正在请求无效 auth_token 或用户可能不存在于您的数据库中。 你还需要更正这个

def logout
  current_user.invalidate_token
end

抱怨 @current_usernil,因此在 @current_user 上使用 invalidate_token 之前,请确保 @current_user 不是 nil

我猜你在application_controller中使用current_user method,returns @current_user 所以替换

 def logout
   @current_user.invalidate_token
 end

 def logout
   current_user.invalidate_token
 end

您在 authenticate_token 中获取用户记录时正在执行 find_by。如果没有找到记录,则返回 nil

您的数据有误,或者您的 header 无效。