为何需验证JWT签发后用户密码未发生变更?
为什么JWT授权时要检查密码是否在签发后变更?
这步校验的核心目的是即时失效已过期的权限凭证,避免用户密码变更后,旧的JWT还能被用来访问系统,本质是筑牢账号安全的防线。
具体场景拆解:
- 密码被盗后的紧急补救:假设用户账号密码泄露,盗号者拿到了未过期的JWT。用户发现后立刻修改了密码,如果没有这步校验,盗号者依然可以用旧token继续操作账号,密码变更的安全补救意义就完全丧失了。
- 用户主动更换密码:用户改密码可能是因为不想再用旧密码,或者怀疑账号有风险。此时所有之前签发的旧token都应该失效,确保只有用新密码重新登录拿到的token才有效,完全符合用户对账号权限的预期。
代码逻辑解析
先看你实现的changedPasswordAfter方法:
Schema.methods.changedPasswordAfter = function(JWTTimestamp) { if(this.passwordDateAt) { const changeTimeStamp = parseInt(this.passwordDateAt / 1000 , 10); // 对比JWT签发时间与密码修改时间:若JWT签发早于密码修改,说明改密码在token生成之后 return JWTTimestamp < changeTimeStamp; } return false; }
这个方法的作用就是判断:当前用户的密码修改时间,是否晚于JWT的签发时间。如果是,说明用户在拿到这个token之后修改了密码,那这个旧token就应该作废,必须重新登录获取新的有效token。
再回到protect中间件里的校验逻辑:
if(freshUser.changedPasswordAfter(decoded.iat)){ return next(new AppError('User recently changed the password, Please log in again',401)); }
这里的decoded.iat是JWT的签发时间(Issued At),调用上面的方法后,如果返回true,就直接返回401权限错误,拒绝旧token的访问请求,强制用户重新登录。
总结:这步校验是账号安全的关键防线,确保权限凭证的有效性和用户操作的一致性,避免密码变更后出现权限失控的情况。
内容的提问来源于stack exchange,提问作者David Aesthetic
相关产品推荐
相关产品推荐

