JWT实战避坑:12个开源项目里翻车的6个共同问题
很多开发者写JWT(JSON Web Token)的时候习惯直接复制教程里的Demo,结果把安全隐患也一起copy进去了。我之前翻了12个Node.js开源项目,从几千星的模板到公司实际在用的脚手架,发现大家踩的坑惊人地一致。
进阶方案: 使用
实战建议: Access Token 设为 15 分钟,需要长会话的话,请部署一套 Refresh Token 机制。
下一篇
纯浏览器端跑AI模型:三个实战工具带给我的血泪教训 →
这些项目代码质量其实不错,但JWT这块细节太容易被忽视。分享几个最典型的实操错误,大家对号入座检查下自己的代码。
一、把 "secret" 当成了真正的密钥
这是最离谱的。我在三个项目里直接看到了这样的写法:
const token = jwt.sign({ userId: user.id }, "secret", { expiresIn: "1h" });这种6位字符的密钥熵值极低,大概只有42 bits。用GPU跑个字典攻击,毫秒级就能破解。记住,教程里的 "secret" 只是占位符。一个合格的256位随机密钥才是生产环境的底线。二、在鉴权中间件里误用 jwt.decode()
很多同学分不清 decode 和 verify 的区别。我在一个生产环境的中间件里看到这种写法:
// 极其危险:仅解码,不验证签名
const decoded = jwt.decode(req.headers.authorization.split(" ")[1]);
if (!decoded.userId) return res.status(401).send("Unauthorized");jwt.decode() 只是把 Base64 编码的 payload 还原成 JSON,它根本不去检查签名是否正确。这意味着攻击者随便伪造一个 payload,只要格式对,就能绕过验证。正确做法: 必须用 jwt.verify()。
const decoded = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ["HS256"] });三、verify() 时没指定算法
即便用了 verify(),如果没写 { algorithms: ['HS256'] },很多库会默认信任 Token 头部(Header)里声明的算法。
如果攻击者把算法改成 alg: none 并把签名部分删掉,某些版本的库会直接判定为合法。所以,显式指定算法是必须的。
四、密钥直接 commit 到 Git 仓库
在某个 config.js 里我看到了这种操作:
module.exports = {
jwtSecret: "productionsecretdonotshare2024", // 开发者还特意标注了不要分享
database: process.env.DATABASE_URL
};只要进入了 Git 历史记录,这个密钥就永久失效了。即便你后来删了这行代码,通过 git log 依然能找回来。一旦泄露,必须立即更换(Rotate)密钥。五、前端把 Token 存在 localStorage
这是前端开发最常见的习惯:
localStorage.setItem("token", response.data.token);localStorage 对页面上所有 JS 脚本都是可见的。如果项目里有一个 XSS 漏洞(比如某个评论区没做转义,或者引入的第三方 npm 包有后门),Token 会瞬间被窃取。进阶方案: 使用
httpOnly 的 Cookie。这种 Cookie 在 JS 层面不可见,能从根源上防御 XSS 窃取 Token。六、Token 永不过期
很多代码在 sign 的时候漏掉了 expiresIn 参数:
const token = jwt.sign({ userId: user.id }, secret);没有 exp 声明的 Token 除非手动吊销(而 JWT 很难吊销),否则永远有效。一旦泄露到日志或缓存里,攻击者就拿到了永久通行证。实战建议: Access Token 设为 15 分钟,需要长会话的话,请部署一套 Refresh Token 机制。
最后给个简单的 Pre-ship 检查清单,上线前对照一下:
- 密钥强度: 是否通过 CSPRNG 生成且至少 256 bits?
- 存储位置: 密钥是否在
.env环境变量中,而非代码里? - 验证逻辑: 全局是否禁用了
jwt.decode(),统一使用jwt.verify()? - 算法限制:
verify时是否显式传入了{ algorithms: ['HS256'] }? - 过期策略: 每个 Token 是否都带了合理的
exp时间?
全部回复 (2)
夜
夜猫子创业者
专家
10小时前
那要是密钥不小心传到Git上了,除了赶紧改掉还能怎么补救?
0
小