护照-jwt令牌过期

18

我正在使用passport-jwt生成我的令牌,但是我注意到这些令牌从不过期。是否有任何方法根据为我设置的规则使特定令牌失效,例如:

'use strict';
const passport = require('passport');
const passportJWT = require('passport-jwt');
const ExtractJwt = passportJWT.ExtractJwt;
const Strategy = passportJWT.Strategy;
const jwt = require('../jwt');
const cfg = jwt.authSecret();

const params = {
    secretOrKey: cfg.jwtSecret,
    jwtFromRequest: ExtractJwt.fromAuthHeader()
};

module.exports = () => {
    const strategy = new Strategy(params, (payload, done) => {
        //TODO: Create a custom validate strategy
        done(null, payload);
    });
    passport.use(strategy);
    return {
        initialize: function() {
            return passport.initialize();
        },
        authenticate: function() {
            //TODO: Check if the token is in the expired list
            return passport.authenticate('jwt', cfg.jwtSession);
        }
    };
};

或者一些策略来使一些令牌失效


你能解决它吗? - Mr. B.
4个回答

28

JWT的标准是将过期时间作为"exp"包含在有效负载中。如果这样做,passport-JWT模块会自动遵循它,除非你明确告诉它不要这样做。比起自己实现,这样更简单。

编辑

现在来看一些代码!

我通常使用npm模块jsonwebtoken来创建/签署我的令牌,其中有一个选项可以使用友好的时间偏移量设置过期时间在有效载荷的exp元素中。它的用法如下:

const jwt = require('jsonwebtoken');

// in your login route
router.post('/login', (req, res) => {
  // do whatever you do to handle authentication, then issue the token:

  const token = jwt.sign(req.user, 's00perS3kritCode', { expiresIn: '30m' });
  res.send({ token });
});

根据我所看到的,您的JWT策略可以保持原样,它将自动尊重我上面设置的30分钟过期时间(当然,您也可以设置其他时间)。


如何延长令牌的生命周期是最佳实践?例如,如果用户想在应用程序中停留超过30分钟怎么办? - trojek
这是通过通常称为“刷新令牌”的方式完成的,基本上意味着您针对特定端点请求新的身份验证令牌。客户端应用程序通常需要积极处理此问题。更多细节请参见:https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/ - Paul
1
我添加了 expiresIn: '10s' 但是不起作用。令牌在10秒后才能使用。 - iamcrypticcoder
@iamcrypticcoder 同样,令牌永不过期。 - Jplus2

2
您可以使用以下策略生成有效期为1小时的JWT令牌:"最初的回答"。
let token = jwt.sign({
    exp: Math.floor(Date.now() / 1000) + (60 * 60),
    data: JSON.stringify(user_object)
}, 'secret_key');
res.send({token : 'JWT '+token}) 

0

如果你想以秒为单位操纵expiresIn

const { sign } = require('jsonwebtoken');

function generateToken(id) {
  const options = {
    expiresIn: 10, // seconds
    algorithm: 'RS256'
  };
  const payload = {
    sub: id,
    iat: Math.floor(Date.now() / 1000)
  };
  return sign(payload, 'PRIVATE_KEY', options);
}

-5

我在数据库中创建了一个文档,用于存储生成的令牌,并添加了过期日期。当用户发出请求时,请检查令牌是否已过期。

这是我使用的验证策略。

/* ----------------------------- Create a new Strategy -------------------------*/
const strategy = new Strategy(params, (payload, done) => {

    const query = {
        token: jwtSimple.encode(payload, credentials.jwtSecret),
        expires: {$gt: new Date()}
    };

    TokenSchema.findOne(query, (err, result) => {
        if (err) done(err, null);
        if (!result) done(null, null);
        done(null, payload);
    });
});
passport.use(strategy);
/* -------------------------------------------------------------------------------*/

这对我有效。


9
如果你仍在这样做,我建议停止。这样做会忽略JWT的整个意义,因为它们应该是无状态的。 - Ernest Zamelczyk
2
没错,这是一种不好的做法。有更好的有状态方法替代方案。 - Marc DiMillo
如前所述,JWT是无状态的,不应存储在数据库中。 - stefano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接