FeathersJS中基于JWT的认证与会话处理疑问
FeathersJS JWT认证常见疑问解答
我来帮你拆解这些实际开发中常碰到的FeathersJS JWT认证问题:
1. JWT访问令牌存储于何处?
FeathersJS 默认不会在服务端存储JWT令牌本身——令牌生成后会直接返回给客户端,由客户端负责保存。常见的客户端存储方式包括:
- 浏览器环境:
localStorage、sessionStorage或 HttpOnly Cookie(更安全,能防范XSS) - 移动端:系统提供的安全存储容器(比如iOS的Keychain、Android的Keystore)
如果你启用了Redis令牌吊销功能,服务端只会存储需要吊销的令牌ID(即JWT payload里的jti字段),用来在验证时检查令牌是否被拉黑,这不属于存储令牌本身,只是维护一个吊销清单。
2. 该JWT是有状态还是无状态?
默认情况下,FeathersJS的JWT认证是无状态的:
- 服务端不需要在内存或数据库中保存用户会话信息,所有必要的身份数据都编码在JWT的payload里(默认仅包含用户ID,也就是
userId字段;如果你没找到这个字段,可以检查authentication.js配置文件里的jwt.payload选项,确保它包含userId,也可以自定义payload添加其他需要的用户信息)。 - 当你启用Redis令牌吊销后,就变成了半有状态:服务端需要依赖Redis跟踪已吊销的令牌,但核心身份验证依然靠JWT本身的签名有效性,只是多了一步吊销检查。
3. 会话维护相关问题
若为有状态(半有状态):
不需要维护传统的服务端会话(比如Express的express-session)。服务端只需要在验证JWT时,额外查询Redis确认该令牌的jti不在吊销列表中即可,身份信息依然由JWT本身提供。
若为无状态:
服务端完全不需要维护会话。客户端每次请求携带Authorization: Bearer <token>,服务端通过验证JWT的签名、过期时间,解码出payload里的用户ID,再根据ID从数据库获取完整用户信息(如果业务需要的话)。
如果你的业务需要维护用户临时状态(比如购物车、临时偏好),可以将这些状态存储在数据库或Redis中,用用户ID作为关联键,而非依赖传统会话。
4. 关于刷新令牌的实现
FeathersJS官方默认认证流程确实没有内置刷新令牌功能,但你可以通过扩展认证服务自定义实现,这是业界通用的方案:
- 大致步骤如下:
- 用户登录成功后,除了返回
accessToken,额外生成一个refreshToken(可以是另一个JWT,也可以是随机字符串)。 - 将
refreshToken与用户ID关联,存储到Redis或数据库中,并设置比accessToken更长的过期时间。 - 新增一个刷新令牌接口,客户端在
accessToken过期后,携带refreshToken请求该接口。服务端验证refreshToken的有效性(检查是否存在、是否过期、所属用户是否匹配),验证通过后生成新的accessToken返回给客户端。 - 当用户注销或需要吊销刷新令牌时,从存储中删除对应的
refreshToken即可。
- 用户登录成功后,除了返回
你可以基于Feathers的自定义服务来实现这个逻辑,社区也有一些第三方插件可以参考,但核心逻辑还是需要自己根据业务需求调整。
内容的提问来源于stack exchange,提问作者Sandeep Kadam
相关产品推荐
相关产品推荐

