悠悠楠杉
JWT过期时间设置不生效:从"7d"到"7h"的深夜调试实录
正文:
凌晨三点的屏幕荧光刺得眼睛生疼,咖啡杯早已见底。我盯着控制台输出的JWT令牌,第37次尝试将过期时间从"7d"改成"7h",可解码后的exp字段依然固执地显示七天后过期。这问题像一根卡在喉咙的鱼刺——看似简单,却让人寝食难安。
第一幕:迷雾中的配置项
项目采用Node.js+Express架构,JWT签发逻辑封装在authService.js中:javascript
const token = jwt.sign(
{ userId: user.id },
process.env.JWT_SECRET,
{ expiresIn: '7h' } // 明明改成了7小时
);
环境变量通过dotenv加载,.env文件赫然写着:ini
JWT_EXPIRES_IN=7h
JWT_SECRET=my_super_secret
甚至尝试硬编码:javascript
{ expiresIn: '7h' } // 直接写死参数
但用https://jwt.io解码后,过期时间仍是604800秒(7天)。这见鬼的7d阴魂不散!
第二幕:依赖库的暗箭
排查进入死胡同时,突然想起项目中的config/index.js:javascript
module.exports = {
jwt: {
expiresIn: process.env.JWT_EXPIRES_IN || '7d' // 环境变量兜底7天?
}
};
但在代码中并未使用这个配置,难道是...?
执行console.log(process.env)时,发现一个诡异现象:javascript
{
JWT_EXPIRES_IN: '7d', // 环境变量竟然是旧值?!
NODE_ENV: 'development'
}
原来团队引入了第三方配置库,其config/default.js中写着:json
{
"jwt": {
"expiresIn": "7d"
}
}
致命发现:该库会自动将配置项转为环境变量,并以CONFIG_FORCE_为前缀强制覆盖!此时在终端执行:bash
printenv | grep JWT
输出结果如五雷轰顶:CONFIG_FORCE_jwt__expiresIn=7d
JWT_EXPIRES_IN=7h
环境变量优先级顺序:CONFIG_FORCE_ > 普通环境变量 > .env文件。旧配置像特洛伊木马般潜伏在系统中!
第三幕:版本差异的陷阱
解决环境变量冲突后,问题仍未消失。翻出package.json:json
"dependencies": {
"jsonwebtoken": "^8.5.1"
}
查源码时发现v8.5.1的签名函数有段玄机:javascript
// jsonwebtoken/lib/sign.js
if (options.expiresIn) {
var exp = claim.iat + (options.expiresIn); // 直接相加?!
}
而新版v9.0.0已修复:javascript
// 新版处理逻辑
if (typeof payload.exp !== 'number') {
payload.exp = iat + timespan(options.expiresIn);
}
原来旧版对expiresIn字符串(如"7h")解析存在bug!紧急升级后:bash
npm install jsonwebtoken@9.0.0
最终解决方案
组合拳出击:
1. 清除环境变量污染bash
unset CONFIG_FORCE_jwt__expiresIn
2. 升级依赖库json
"jsonwebtoken": "^9.0.2"
3. 显式转换时间单位javascript
// 添加容错处理
const expiresIn = typeof options.expiresIn === 'string' ?
ms(options.expiresIn) / 1000 : // 转为秒数
options.expiresIn;
4. 终极验证脚本javascript
const token = jwt.sign({}, 'secret', { expiresIn: '7h' });
const decoded = jwt.decode(token, { complete: true });
console.log(decoded.header); // 检查alg等头部
console.log(new Date(decoded.payload.exp * 1000)); // 精确到毫秒的时间戳
(后记:两周后在生产环境发现另一个陷阱——某些JWT库要求expiresIn必须带单位后缀,纯数字会按毫秒解析!但那是另一个午夜惊魂的故事了...)
