Passport-jwt 令牌过期

Posted

技术标签:

【中文标题】Passport-jwt 令牌过期【英文标题】:Passport-jwt token expiration 【发布时间】:2017-03-04 10:07:15 【问题描述】:

我正在使用 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);
        
    ;
;

或一些使某些令牌无效的策略

【问题讨论】:

你能解决吗? 【参考方案1】:

您可以使用以下策略生成过期限制为 1 小时的 JWT-token。

let token = jwt.sign(
    exp: Math.floor(Date.now() / 1000) + (60 * 60),
    data: JSON.stringify(user_object)
, 'secret_key');
res.send(token : 'JWT '+token) 

【讨论】:

【参考方案2】:

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 分钟? 这是通过通常称为“刷新令牌”的方式完成的,这基本上意味着您针对特定端点请求新的身份验证令牌。通常,客户端应用程序必须对此采取主动。更多详情:auth0.com/blog/…【参考方案3】:

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

这是我使用的验证策略。

/* ----------------------------- 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);
/* -------------------------------------------------------------------------------*/

这对我有用。

【讨论】:

如果你还在这样做,我建议停止。您错过了 JWT 的全部意义,因为它们应该是无状态的。 是的,这是不好的做法。有状态方法的更好替代方案。 如前所述,JWT 是无状态的,不应存储在数据库中

以上是关于Passport-jwt 令牌过期的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 passport-jwt 正确检查令牌有效负载?

NodeJs Express passport-jwt 从令牌中获取错误的用户

Passport-jwt 不同的令牌相同的结果

如何使用passport-jwt在nodejs中发送/提取JWT令牌?

设置 passport-jwt 身份验证

混合护照-facebook和passport-jwt的最佳方法是什么?