Rails中devise-jwt登录后未更新User模型jti属性的问题
解决Devise-JWT的JTIMatcher策略登录后不更新jti的问题
我之前也碰到过一模一样的困惑,完全懂你的感受——默认情况下,Devise::JWT::RevocationStrategies::JTIMatcher 策略并不会在用户每次登录时自动更新jti字段,这和你预期的自动更新行为确实有出入。
为什么jti不会自动更新?
JTIMatcher的核心设计逻辑是通过对比token中的jti和数据库里的jti来实现token撤销:当用户执行登出操作时,gem会调用revoke_jwt方法生成新的jti,这样之前的token因为jti不匹配就会直接失效。但登录操作默认不会触发这个逻辑,gem会复用用户已有的jti生成新token,所以你才会看到jti从未更新。
如何实现登录时自动更新jti?
如果你的需求是每次登录都让之前的所有token失效,那么确实需要手动添加登录回调来更新jti,这是符合当前gem设计逻辑的操作。具体可以这么做:
在你的User模型中添加登录后的回调:
class User < ApplicationRecord include Devise::JWT::RevocationStrategies::JTIMatcher devise :database_authenticatable, :recoverable, :trackable, :validatable, :jwt_authenticatable, jwt_revocation_strategy: self # 添加登录后更新jti的回调 after_sign_in :rotate_jti def jwt_payload super.merge({ custom: 'data' }) end private def rotate_jti # 用update_column跳过验证直接更新字段,避免不必要的校验 update_column(:jti, SecureRandom.uuid) # 如果需要触发模型回调,也可以用update!: # update!(jti: SecureRandom.uuid) end end
额外注意事项
- 确认你的
devise.rb配置中已经正确设置了JWT的分发和撤销路由,比如:Devise.setup do |config| # 其他配置... config.jwt do |jwt| jwt.secret = ENV['DEVISE_JWT_SECRET_KEY'] # 登录请求分发token jwt.dispatch_requests = [['POST', %r{^/login$}]] # 登出请求触发撤销(此时JTIMatcher会自动更新jti) jwt.revocation_requests = [['DELETE', %r{^/logout$}]] end end - 如果你不需要每次登录都失效旧token,只是疑惑为什么登出时
jti也没更新,那需要检查登出接口是否正确触发了Devise的撤销逻辑(比如是否调用了jwt_revocation_strategy的revoke_jwt方法)。
内容的提问来源于stack exchange,提问作者Taylor Allred
相关产品推荐
相关产品推荐

