如何使用护照认证更新包含jwt的cookie

时间:2019-02-13 11:16:47

标签: node.js authentication cookies jwt passport.js

我有一个包含签名的jwt的cookie,有效5分钟。 jwt包含基本用户信息(用于身份验证),以及全局唯一ID(GUID)。如果这些guid有效,我会将它们存储在数据库中,并且在jwt到期后的下一个请求中,我想要: 1.)检查数据库中的guid,并确认它仍然有效(未列入黑名单) 2.)使用新的5分钟有效期和相同信息更新cookie中的jwt 我遇到了很多错误,但是我尝试过的任何方法都没有奏效,而且我很好奇目前是否可行或正确的方法。 我正在使用节点js包“ passport-jwt”和“ jsonwebtoken”一起创建jwts并进行验证。 ////////////////////// //authorization.js ////////////////////// const JWTStrategy = require('passport-jwt')。Strategy; const jwt = require('jsonwebtoken'); const mongoose = require('mongoose'); require('../ models / Guids'); const Guids = mongoose.model('Guids'); module.exports.JWTStrategy =函数(护照){     password.use('jwt',新的JWTStrategy({         jwtFromRequest:req => cookieExtractor(req,'token'),         secretOrKey:'秘密',         passReqToCallback:true     },         (要求,jwt_payload,已完成)=> {             如果(Date.now()/ 1000> jwt_payload.exp){                 Guids.findOne({_id:jwt_payload.guid,userId:jwt_payload.uid})                     .then(guid => {                     如果(guid.valid){                             //在这里刷新令牌                             // ?????????返回完成(null,jwt_payload);                         }其他{                             //强制用户重新认证                             // ???????返回已完成(“访问令牌已过期”);                         }                 })                 .catch(err => {                     console.log(err);                     返回完成(“无法验证用户”);                 });             }其他{                 返回完成(null,jwt_payload);             }         }     )); }; var cookieExtractor =函数(req,tokenName){     var token = null;     if(req && req.cookies){         令牌= req.cookies [tokenName];     }其他{         console.log('未找到cookie');     }     返回令牌; }; - ///////////////////////////// //app.js ///////////////////////////// const express = require('express'); const cookieParser = require('cookie-parser'); const bodyParser = require('body-parser'); 常量护照= require('passport'); const jwt = require('jsonwebtoken'); const app = express(); require('./ authorization')。JWTStrategy(passport); app.use(bodyParser.urlencoded({Extended:false})); app.use(bodyParser.json()); app.use(cookieParser()); //受保护的路线 app.get('/ xyz',passport.authenticate('jwt',{session:false}),(req,res)=> {     //路由逻辑... }); //登录路由(创建令牌) app.post('/ login',(req,res,next)=> { 有效载荷= {     guid:12345678901010101',     uid:“ 123456789”, }; req.login(payload,{session:false},(err)=> {     如果(错误){         console.log(err);     }其他{         const token = jwt.sign(payload,'secret',{expiresIn:'30s'});         res.cookie('token',令牌,{httpOnly:true});         res.redirect('/ xyz');     };     } } const port = process.env.PORT || 5000; const server = app.listen(port,()=> {     console.log(`服务器在端口$ {port}上启动); }); 默认情况下,当令牌过期时,受保护路由上的身份验证中间件会立即引发故障。 我想绕过此故障,而是在“ authorization.js”文件中执行一些代码,其中注释为“在此处刷新令牌”。 由于自动失败,甚至没有达到那行代码!我尝试过在到期之前和之后进行控制台日志记录。 我什至以前都手动绕过了自动失败,但是包含cookie的响应对象(res)在password-jwt策略中不可用。如果指定的位置由于是中间件功能而变得毫无意义,那么我在应该在哪里实施该逻辑就有些迷惑了。 另外,如果受保护的路由是POST,并且令牌在成功“获取”页面后过期,那么我希望不妨碍POST方法。我想无缝刷新令牌,然后与POST一起移动。

1 个答案:

答案 0 :(得分:0)

Passport支持自定义消息,或者更精确地支持自定义回调。您必须自己嵌入包装器中间件中,手动调用通行证 authenticate 中间件。这允许访问reqres对象。有关更多详细信息,请参见documentation

  

如果内置选项不足以处理身份验证请求,则可以提供自定义回调以允许应用程序处理成功或失败。

app.get('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/users/' + user.username);
    });
  })(req, res, next);
});