快速中间件中的 Node.js JWT 刷新令牌

Posted

技术标签:

【中文标题】快速中间件中的 Node.js JWT 刷新令牌【英文标题】:Node.js JWT refresh token in express middleware 【发布时间】:2018-07-17 16:11:07 【问题描述】:

我正在尝试在我的 express 中间件中配置一个令牌刷新方法,该方法在对 api 的每个请求时都会验证令牌。我将检查令牌是否过期,如果是,我将签署一个具有新到期日期的新令牌。问题是我必须再次发送令牌,但是这样做我丢失了发送令牌和响应的原始请求,并且 api 不会继续到目标端点。 如何发回新刷新的令牌并继续请求?

我的快速中间件检查令牌:

apiRouter.use(function(req, res, next) 
      var token = req.body.token || req.query.token || req.headers['x-access-token'];
      if (token) 
        jwt.verify(token, app.get('superSecret'), function(err, decoded) 
          if (err) 
            //Here I can check if the received token in the request expired
            if(err.name == "TokenExpiredError")
                var refreshedToken = jwt.sign(
                    success: true,
                    , app.get('superSecret'), 
                        expiresIn: '5m'
                    );
                //Here need to send the new token back to the client and continue with the request
                //but if I use return res.... the request don't continue to next()
                next();
              else if (err) 
                return res.json( success: false, message: 'Failed to authenticate token.' );
                       
           else 
            //If no error with the token, continue 
            next();
          ;
        );
       else 
        return res.status(403).send(
            success: false,
            message: 'No token provided.'
        );
      
    );

我不知道这是否是最好的方法。

谢谢。

【问题讨论】:

【参考方案1】:

您不能为单个请求向客户端发送两次响应,因此更好的方法是发送带有实际 API 响应的访问令牌。

apiRouter.use(function(req, res, next) 
      var token = req.body.token || req.query.token || req.headers['x-access-token'];
      if (token) 
        jwt.verify(token, app.get('superSecret'), function(err, decoded) 
          if (err) 
            //Here I can check if the received token in the request expired
            if(err.name == "TokenExpiredError")
                var refreshedToken = jwt.sign(
                    success: true,
                    , app.get('superSecret'), 
                        expiresIn: '5m'
                    );
                request.apiToken = refreshedToken;
                next();
              else if (err) 
                return res.json( success: false, message: 'Failed to authenticate token.' );
                       
           else 
            //If no error with the token, continue 
            request.apiToken = token;
            next();
          ;
        );
       else 
        return res.status(403).send(
            success: false,
            message: 'No token provided.'
        );
      
    );

然后当您发送响应然后发送带有令牌的响应时,您可以使用 request.apiToken 获得。

但更好的策略是提供客户端刷新令牌,让客户端发出请求以获取刷新令牌。

你可以阅读更多关于here

【讨论】:

谢谢 Ridham,我正在考虑这样做。在这种情况下,如果请求具有 apiToken 属性,我必须在令牌验证/刷新之后检查每条路由,并将其附加到目标路由中的响应。对吗? 是的,但简单的方法是创建一个函数,该函数将根据您的格式生成响应并附加令牌。像这样的东西。我创建这个是为了生成错误codepad.co/snippet/0pUtNxi3。您可以考虑类似的方法来创建统一的响应结构 谢谢 Ridham!

以上是关于快速中间件中的 Node.js JWT 刷新令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何延长node.js中相同jwt令牌的到期时间

黑名单/验证/生成 JWT 刷新令牌

如何将 JWT 令牌发送到 node.js 服务器

Node.js 护照 OAuth 2.0 身份验证:存储访问和刷新令牌的位置

为啥使用 JWT 而不是在 DB 中存储令牌来授权 Node.js 中的访问令牌?

如何在 React.js 应用程序中刷新 JWT 令牌?