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

我用的宝石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

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

回答:

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

假设你携带在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

以上是 应该将令牌存储到Ruby On Rails中的数据库中吗? 的全部内容, 来源链接: utcz.com/qa/258622.html

回到顶部