JWT刷新令牌接口生成与登录接口相同AccessToken的问题咨询
问题分析与解决
你遇到的问题是刷新接口生成的AccessToken和登录接口完全相同,核心原因是刷新时直接使用了从refreshToken解析出的完整用户对象(可能包含旧的JWT声明字段)进行签名,而没有提取核心用户标识,导致两次签名的payload高度一致,最终生成相同的token。
具体问题点:
- 你在
jwt.verify后直接将返回的user对象传入jwt.sign,这个user对象可能包含refreshToken自带的iat(签发时间)、exp(过期时间)等字段,若登录时的accessToken也使用了相同的完整用户对象签名,就会出现token重复的情况。 - 代码存在逻辑与提示信息矛盾的错误:
if (!refreshTokens.includes(refreshToken)) return res.status(403).send("token is valid");,这里应该返回"token is invalid"。
修复方案:
- 只提取用户的核心标识字段(如
id、username)用于生成新的accessToken,避免携带旧的JWT声明字段。 - 修正错误的提示信息。
修改后的代码:
const refreshToken = req.body.token; console.log(refreshToken); if (refreshToken == null) return res.status(401).send("Not authorized"); if (!refreshTokens.includes(refreshToken)) return res.status(403).send("token is invalid"); // 修正提示信息 jwt.verify( refreshToken, "my refresh secret", (err, user: Prisma.User) => { if (err) return console.log(err); // 仅使用核心用户字段生成新的accessToken const accessToken = jwt.sign( { id: user.id, username: user.username }, "my access secret", { expiresIn: "15s" } ); res.json({ accessToken: accessToken }); } ); };
额外说明:
JWT的签名结果由payload内容、签名密钥、算法共同决定,只要这三者完全一致,生成的token就会相同。通过只保留核心用户标识,每次签名时JWT库会自动添加新的iat(当前时间)和exp(当前时间+15s)字段,确保payload唯一,生成的accessToken自然与登录接口不同。
内容的提问来源于stack exchange,提问作者NeridaN
相关产品推荐
相关产品推荐

