我正在Rails 5 API上构建身份验证,并且注销部分出现问题。我碰到了/logout
路由,并在读取NoMethodError: undefined method 'invalidate_token' for nil:NilClass>
时收到500错误,然后它引用了我的sessions_controller。我的sessions_controller在Users模型中声明的注销方法中引用了一个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并实际上使已登录的用户令牌无效。
答案 0 :(得分:1)
有人抱怨@current_user
是nil
,所以在invalidate_token
上使用@current_user
之前,请确保@current_user
不是nil
。
我猜您在current_user
中使用method
application_controller
返回了@current_user
,所以请替换
def logout
@current_user.invalidate_token
end
使用
def logout
current_user.invalidate_token
end
答案 1 :(得分:1)
在获取find_by
中的用户记录时,您正在执行authenticate_token
。如果未找到任何记录,则返回nil
。
要么您的数据不正确,要么标题无效。
答案 2 :(得分:0)
这是因为您的current_user为nil。您必须在发出注销请求时发送auth_token。使用此auth_token,您必须获取用户,以便可以将其更新为-nil auth_token。如果找不到用户,则必须处理这种情况下的异常,因为您的请求使用了无效的auth_token或用户可能不在数据库中。 您还需要纠正此问题
nil <-> 7 <-> 4