如何在JWT中使用jti声明

JWT规范提到了一个jti声明,据称这个声明可以作为随机数来防止重播攻击:

JTI(JWT ID)声明为JWT提供了一个唯一的标识符。 标识符值必须以确保相同值被偶然分配给不同数据对象的可能性可以忽略的方式分配; 如果应用程序使用多个发行者,则必须防止不同发行者产生的值之间的冲突。 jti声明可用于防止重播JWT。 jti值是区分大小写的string。 使用这个声明是可选的。

我的问题是如何去执行这个? 我是否需要存储以前使用的jtis,并在每次请求时发布新的JWT? 如果是这样,这是否不符合智威汤逊的目的? 为什么使用JWT而不是将随机生成的会话ID存储在数据库中?

我的REST API有一个mongo数据库,我不反对增加一个redis实例。 有比JWT更好的身份validation选项吗? 我主要是不想在客户端存储消除HTTPauthentication的密码作为一个选项,但是,当我深入到这个JWT的东西,我开始感觉,如果自定义令牌实施或不同的标准可能会更好满足我的需求。 是否有任何节点/快递包基于令牌的authentication,支持令牌吊销和旋转令牌?

将不胜感激任何意见。

实际上,存储所有已发布的JWT ID都会破坏使用JWT的无状态特性。 但是,JWT ID的目的是能够撤销之前发布的JWT。 这可以通过列入黑名单而不是白名单来实现。 如果你已经包含了“exp”声明(你应该),那么你最终可以清理被黑名单的JWTs,因为它们自然失效。 当然,你也可以实施其他撤销选项(例如,基于“iat”和“aud”的组合来撤销一个客户的所有令牌)。

你可以使用express-jwt包

请参阅GitHub或NPM上的express-jwt。

Express-jwt处理撤销令牌,如下所述: https : //github.com/auth0/express-jwt#revoked-tokens

 var jwt = require('express-jwt'); var data = require('./data'); var utilities = require('./utilities'); var isRevokedCallback = function(req, payload, done){ var issuer = payload.iss; var tokenId = payload.jti; data.getRevokedToken(issuer, tokenId, function(err, token){ if (err) { return done(err); } return done(null, !!token); }); }; app.get('/protected', jwt({secret: shhhhhhared-secret, isRevoked: isRevokedCallback}), function(req, res) { if (!req.user.admin) return res.send(401); res.send(200); }); 

你也可以阅读第4部分。 我们如何避免增加开销? 从这个oauth0博客文章 。