应该将令牌存储到Ruby On Rails中的数据库吗?

时间:2017-12-02 22:31:41

标签: ruby-on-rails ruby devise

我使用gem jwtdevise来构建用户登录系统

我生成模型身份验证以检查令牌是否存在。

请遵循以下代码:

模型/ authentication.rb

class Authentication < ApplicationRecord
  def self.generate_access_token(email)
    payload = {:email => email}
    secret = 'secret'
    token = JWT.encode payload, secret, 'HS256'
    return token
  end
end

控制器/用户/ sessions_controller.rb

def create
    user = User.where(email: params[:email]).first
    if user&.valid_password?(params[:password])
      @token = Authentication.generate_access_token(user.email)
      Authentication.create(access_token: @token)
      authentications = {token: @token, email: user.email}
      render json: authentications, status: :created
    else
      head(:unauthorized)
    end
  end

当我向user/sessions发送请求时,我会收到令牌和用户电子邮件并将其存储在客户端的localstorage中,并帮助我检查令牌是否有效。

请遵循以下代码:

def authenticate_token
  token = Authentication.find_by_access_token(params[:token])
  head :unauthorized unless token
end 

在我的问题中,有没有办法让令牌不需要存储到数据库中?

1 个答案:

答案 0 :(得分:1)

您可以解码令牌并获取存储在其中的电子邮件,并通过该电子邮件找到用户。

假设您在Authorization标题中携带令牌,例如

Authorization: Bearer <token>

然后您可以定义before_action来执行此操作:

class ApplicationController < ActionController::API
  before_action :authenticate_token

  def authenticate_token
    token = request.headers['Authorization'].to_s =~ /^Bearer (.*)$/i && $1
    return head :unauthorized unless token
    payload = JWT.decode(token, 'secret', true, algorithm: 'HS256')
    user = User.find_by(email: payload['email'])
    return head :unauthorized unless user
    # TODO set the `user` as current_user
    # How to patch devise's `current_user` helper is another story
  end
end

如果我是你,我会将用户ID放在令牌中,而不是电子邮件,因为ID更短,从数据库查找更快,并且它不会向互联网公开任何个人信息(注意JWT未加密。它&# 39;刚刚签署。)

或者您可以使用knock代替devise来跳过所有这些混乱的事情。