[英]Should token store into database in Ruby On Rails?
I use the gem jwt
、 devise
to build a user login system, 我使用gem
jwt
, devise
构建用户登录系统,
I generate a model Authentication to check the token exist or not. 我生成一个模型身份验证以检查令牌是否存在。
follow this code: 请遵循以下代码:
models/authentication.rb 车型/ 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
controllers/user/sessions_controller.rb 控制器/用户/ 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
when I do a post request to user/sessions
I will get token and user email and store it in localstorage of client, and help me to check the token is valid. 当我向
user/sessions
发出发布请求时,我将获得令牌和用户电子邮件,并将其存储在客户端的本地存储中,并帮助我检查令牌是否有效。
follow this code: 请遵循以下代码:
def authenticate_token
token = Authentication.find_by_access_token(params[:token])
head :unauthorized unless token
end
In my question, are there ways to let token don't need to store into database? 在我的问题中,有没有办法让令牌不需要存储到数据库中?
You can decode the token and get the email stored in it, and find user by that email. 您可以解码令牌并获取存储在其中的电子邮件,然后通过该电子邮件查找用户。
Suppose you carry the token in the Authorization
header, like 假设您将令牌携带在
Authorization
标头中,例如
Authorization: Bearer <token>
then you can define a before_action
to do this: 那么您可以定义一个
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
If I were you, I would put user ID in the token, not email, because ID is shorter, and faster to lookup from database, and it exposes nothing personal to the internet (note that JWT is not encrypted. It's just signed). 如果您是我,我会将用户ID放在令牌中,而不是电子邮件中,因为ID较短,并且从数据库中查找的速度更快,并且不会对Internet公开任何个人信息(请注意,JWT未加密。它只是经过签名的)。
Or you can skip all these messy things by just using knock instead of devise
. 或者,您可以只使用敲门而不是
devise
来跳过所有这些混乱的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.