Ruby on rails 注销时出错:未定义方法';使令牌无效';

Ruby on rails 注销时出错:未定义方法';使令牌无效';,ruby-on-rails,ruby-on-rails-5,bcrypt,Ruby On Rails,Ruby On Rails 5,Bcrypt,我正在Rails5API上构建身份验证,并且我在注销时遇到了问题。我正在点击/logout路径,收到一个500错误,读取nil:NilClass>的NoMethodError:undefined方法'invalidate\u token',然后它引用我的会话\u控制器。我的sessions\u controller在用户模型中声明的注销方法中引用了一个invalidate\u token方法,当我在模型中定义错误时,我很难理解为什么控制器中没有定义错误 主控主任: class SessionsC

我正在Rails5API上构建身份验证,并且我在注销时遇到了问题。我正在点击
/logout
路径,收到一个500错误,读取nil:NilClass>的
NoMethodError:undefined方法'invalidate\u token',然后它引用我的会话\u控制器。我的sessions\u controller在用户模型中声明的注销方法中引用了一个
invalidate\u token
方法,当我在模型中定义错误时,我很难理解为什么控制器中没有定义错误

主控主任:

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 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

class sessioncontroller
用户模型

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

class用户
API控制器:

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 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

class ApiController

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

这是因为您当前的\u用户为零。您必须在请求注销时发送auth\u令牌。使用此auth_令牌,您必须获取用户,以便可以为--nil auth_令牌更新该用户。如果找不到用户,则必须处理这种情况下的异常,因为您的请求使用了无效的auth_令牌,或者您的数据库中可能不存在用户。 您还需要更正此问题

def logout
  current_user.invalidate_token
end

这是因为您当前的\u用户为零。您必须在请求注销时发送auth\u令牌。使用此auth_令牌,您必须获取用户,以便可以为--nil auth_令牌更新该用户。如果找不到用户,则必须处理这种情况下的异常,因为您的请求使用了无效的auth_令牌,或者您的数据库中可能不存在用户。 您还需要更正此问题

def logout
  current_user.invalidate_token
end

它抱怨
@current\u user
nil
,因此在
@current\u user
上使用
无效\u令牌之前,请确保
@current\u user
不是
nil

我猜您正在
应用程序\u控制器中使用
当前用户
方法
,该方法返回
@current\u用户
,因此请替换

 def logout
   @current_user.invalidate_token
 end


它抱怨
@current\u user
nil
,因此在
@current\u user
上使用
无效\u令牌之前,请确保
@current\u user
不是
nil

我猜您正在
应用程序\u控制器中使用
当前用户
方法
,该方法返回
@current\u用户
,因此请替换

 def logout
   @current_user.invalidate_token
 end


authenticate\u token
中获取用户记录时,您正在执行
find\u by
。如果未找到记录,则返回
nil


您得到的数据不正确,或者您的标题无效。

身份验证令牌中获取用户记录时,您正在执行
查找方法。如果未找到记录,则返回
nil


您得到的数据不正确,或者您的标题无效。

这意味着
@current\u user
丢失,实际上
nil
,就在这里
@current\u user.invalidate\u令牌
。确保
@current\u user
这意味着
@current\u user
丢失,实际上
nil
,就在这里
@current\u user.使\u令牌无效
。请确保
@current_user
我在API控制器中确实有
current_user
方法,但进行您建议的更改恐怕不会对错误产生影响。我已经发布了API控制器供您参考,以防它有助于进一步阐明这个问题,谢谢您的回复!另外,我不会在注销请求中发送任何标题,此请求不需要任何标题,对吗?您应该发送标题我在API控制器中确实有一个
current\u user
方法,但您建议的更改恐怕不会对错误产生影响。我已经发布了API控制器供您参考,以防它有助于进一步阐明这个问题,谢谢您的回复!另外,我不会随注销请求发送任何标题,此请求不需要任何标题,对吗?您应该发送标题,因为这样做不会对错误消息产生影响。可能是因为发送请求时缺少标题吗?我还发布了API控制器,因为您已回复,以防有更多可能与此问题相关的信息,感谢您的回复!不幸的是