终端显示完整JWT,浏览器中JWT不完整的问题求助
问题根源:混淆了Refresh Token和Access Token的作用
你看到的浏览器Cookie里的JWT是Refresh Token,而包含UserInfo和角色信息的是Access Token,两者的设计逻辑本来就不同:
1. 两者的生成逻辑差异
从你的代码可以明确区分:
- Access Token(含用户权限):在
handleLogin和handleRefreshToken中,用ACCESS_TOKEN_SECRET签名,Payload包含UserInfo(邮箱+角色),有效期30分钟,通过响应JSON返回给前端:
const accessToken = jwt.sign( { UserInfo: { email: foundUser.email, roles: roles, }, }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '30m' } ); res.json({ roles, accessToken }); // 直接返回给前端
- Refresh Token(仅用于刷新令牌):用
REFRESH_TOKEN_SECRET签名,Payload仅包含邮箱,有效期1天,存储在httpOnly的Cookie中:
const newRefreshToken = jwt.sign( { email: foundUser.email }, process.env.REFRESH_TOKEN_SECRET, { expiresIn: '1d' } ); res.cookie('jwt', newRefreshToken, { httpOnly: true, sameSite: 'None', secure: true, maxAge: 24 * 60 * 60 * 1000, });
2. 为什么终端和Postman能看到完整JWT
- 终端的
console.log如果打印的是accessToken,自然能看到包含UserInfo的完整内容; - Postman中你既可以看到响应JSON里的
accessToken,也能看到Cookie里的refreshToken,但你误将两者混淆,以为Cookie中的令牌应该包含权限信息。
3. 修正方案
前端需按以下逻辑处理:
- 接收登录/刷新令牌接口返回的
accessToken,将其存储在内存(如状态管理工具)或安全存储中(不建议存localStorage,易遭XSS攻击); - 每次请求需权限校验的接口时,在请求头的
Authorization字段携带Bearer ${accessToken}; - 仅当
accessToken过期时,才用Cookie里的refreshToken调用刷新接口,获取新的accessToken。
不要尝试从Cookie的jwt(Refresh Token)中解析用户权限,它的唯一作用就是申请新的Access Token。
内容的提问来源于stack exchange,提问作者kodingkaiser
相关产品推荐
相关产品推荐

