2017-12-02 354 views
0

我用的宝石jwtdevise建立一个用户登录系统,应该将令牌存储到Ruby On Rails中的数据库中吗?

我生成模型验证检查令牌存在与否。

遵循此代码:

型号/ 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 

当我做一个POST请求user/sessions我会得到令牌和用户的电子邮件并将其存储在客户端的本地存储中,并帮助我检查令牌是否有效。

遵循此代码:

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

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

回答

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没有加密,只是签名)。

或者你可以跳过所有这些凌乱的事情,只需使用knock而不是devise

+0

非常感谢,它的工作 –

相关问题