React+Axios调用刷新Token接口报JWT invalid signature错误
React自定义Hook刷新Token报invalid signature错误修复方案
核心错误原因
报invalid signature(无效签名)的直接原因是:你传给刷新接口的Token类型不对。
后端刷新接口使用myJwt.refreshSecretKey(刷新Token专用密钥)校验传入的Token,但前端请求时放在Authorization头里的Auth.auth.token是登录时拿到的accessToken(访问Token)——accessToken是用访问专用密钥签名的,用刷新密钥校验自然会报签名不匹配。
Postwoman测试能正常通过,是因为你手动在请求头里填了正确的refreshToken,没有传混。
具体修复步骤
- 拆分前端存储的Token类型
不要把accessToken和refreshToken存在同一个token字段里混用。调整useAuth维护的鉴权状态,分开存储两个字段:
登录成功、刷新Token成功时,分别更新对应字段,不要互相覆盖。// 鉴权状态示例结构 { accessToken: '', // 普通接口请求用,有效期短 refreshToken: '' // 仅刷新接口用,有效期长 } - 修正刷新接口的请求传参
调用刷新接口时,Authorization头必须传入存储的refreshToken,而非当前正在使用的accessToken:const response = await axios.get("user/refresh", { withCredentials: true, headers: { Authorization: `Bearer ${Auth.auth.refreshToken}` // 这里改传refreshToken } }) // 更新状态时分别赋值 Auth(prev => { return { ...prev, accessToken: response.data.accessToken, refreshToken: response.data.refreshToken } }) - 修复后端刷新接口的逻辑缺陷
现有后端代码存在两个明显问题,调整后代码如下:exports.refreshToken = (req, res) => { // 加容错,避免authorization头不存在时split报错 const oldToken = req.headers.authorization?.split(" ")[1] if(oldToken == null ) return res.status(401).send({message: "Token is empty"}) jwt.verify(oldToken, myJwt.refreshSecretKey, (err, user) => { if(err) { // 这里必须加return,否则err时代码会继续向下执行 return res.status(403).send({ msg: err || "Error on refreshing your token" }) } // 刷新时要同时生成新的accessToken和refreshToken(安全轮换机制) const newAccessToken = generateAccessToken(user) const newRefreshToken = generateRefreshToken() res.send({ accessToken: newAccessToken, refreshToken: newRefreshToken }); }) }; - 排查Axios拦截器冲突
检查你自定义的axios实例是否配置了全局请求拦截器自动给所有请求加accessToken:如果拦截器逻辑覆盖了刷新接口手动设置的Authorization头,也会导致传参错误。可以给刷新接口单独配置一个不走全局拦截器的axios实例,或者在拦截器中判断请求路径为user/refresh时,跳过自动注入accessToken的逻辑。
内容的提问来源于stack exchange,提问作者janice bryant
相关产品推荐
相关产品推荐

