Node.js+Express项目中express-jwt-blacklist实现JWT服务端失效失败问题求助
解决express-jwt-blacklist令牌失效不生效的问题
看起来你的核心问题是认证中间件没有检查黑名单状态,导致调用blacklist.revoke()后,令牌依然能通过校验。下面一步步帮你排查修复:
1. 认证中间件缺失黑名单校验逻辑
你的isAuthenticated函数只做了JWT签名验证,完全没有检查令牌是否被加入黑名单。express-jwt-blacklist的revoke()只是把令牌标记为失效,但你需要主动校验这个状态。
修改后的认证中间件代码:
var isAuthenticated = async function(req, res, next) { if (typeof req.headers.authorization !== "undefined") { let token = req.headers.authorization.split(" ")[1]; let privateKey = fs.readFileSync('/private.pem', 'utf8'); try { const user = jwt.verify(token, privateKey, { algorithm: "HS256" }); // 关键:检查令牌是否在黑名单中 const isRevoked = await blacklist.isRevoked(user.jti); // 对应你配置的tokenId: 'jti' if (isRevoked) { return res.render('loginPage.ejs'); } return next(); } catch (err) { return res.render('loginPage.ejs'); } } else { res.render('loginPage.ejs'); } }
2. 确保JWT令牌包含jti字段
你配置了tokenId: 'jti',这意味着express-jwt-blacklist会用令牌中的jti(JWT唯一ID)作为黑名单标识。如果生成令牌时没有添加这个字段,黑名单功能会完全失效。
生成JWT时必须加入jti,示例代码:
const jwt = require('jsonwebtoken'); const { v4: uuidv4 } = require('uuid'); // 需要先安装uuid包:npm install uuid // 生成用户令牌的函数 const generateAuthToken = (user) => { return jwt.sign( { userId: user.id, jti: uuidv4() // 生成唯一的JWT ID }, fs.readFileSync('/private.pem', 'utf8'), { algorithm: 'HS256', expiresIn: '1h' // 建议设置过期时间,作为黑名单的兜底方案 } ); }
3. 检查Memcached配置与运行状态
你的黑名单存储用了Memcached,需要确保:
- Memcached服务正在本地127.0.0.1:11211运行
- 可以通过
telnet 127.0.0.1 11211测试连接是否正常 - 如果是开发环境,也可以临时改用内存存储(
store: { type: 'memory' })来排除Memcached的问题
额外注意事项
strict: true配置意味着只有包含jti字段的令牌才会被黑名单处理,所以必须保证令牌生成时包含该字段- 生产环境建议给JWT设置合理的过期时间,即使黑名单服务故障,令牌也不会永久有效
- 如果你用的是异步存储(比如Memcached),
blacklist.isRevoked()是异步函数,必须用await或Promise处理
内容的提问来源于stack exchange,提问作者init
相关产品推荐
相关产品推荐

