使用刷新令牌签署jwt令牌作为有效负载

时间:2017-11-03 22:11:13

标签: javascript express authentication jwt

我如何理解基于jwt的身份验证应该有效:

  1. 客户端将登录凭据发送给服务器。
  2. 服务器验证凭据是否正确,并使用签名的jwt令牌和刷新令牌进行响应,同时还将刷新令牌存储在数据库中。
  3. 客户端在所有请求中使用jwt标记作为Authentication标头。
  4. 当jwt令牌过期时,服务器以401 Unauthorized回复。
  5. 客户端使用Authentication标头中的刷新令牌发送刷新jwt令牌的请求。
  6. 服务器检查刷新令牌是否存在于数据库中且未过期。然后使用新的jwt令牌进行响应
  7. 客户可以继续使用新令牌进行请求。
  8. 我想如何实现它:

    如果上面的描述是正确的,那么将刷新令牌作为签名的jwt令牌的有效负载是否有任何问题?:

    function signToken(id, role, refresh_token) {
        return jwt.sign(
            {
                _id: id,
                role: role,
                refresh_token: refresh_token
            },
            config.jwt.secret,
            {
                expiresIn: 60*60*24, // expires in 1 day
            }
        );
    }
    

    以这种方式总是在每个请求中发送刷新令牌和jwt令牌?通过执行此操作,客户端不必使用刷新令牌发送单独的请求以获取新的jwt令牌:

    1. 与上述相同
    2. 与上述相同
    3. 与上述相同
    4. 当jwt令牌已过期时,服务器从jwt令牌中挑选刷新令牌并检查它是否存在于数据库中且未过期。
    5. 服务器使用requesed资源+新的jwt令牌进行响应。
    6. 客户端发现响应中有一个新令牌,并将其保存以供进一步请求。
    7. Auth中间件看起来像这样:

      function authenticate (req, res, next) {
      
          // Token attached to request in previous middleware
          let token = req.token
      
          // verifies secret and checks exp
          jwt.verify(token, config.jwt.secret, {ignoreExpiration: true}, (err, decoded) => {
              if (err) {
                  return res.status(500).json({ success: false, message: err.message });
              }
              //Expired token, try to refresh
              if(decoded.exp*1000 < Date.now()){
                  User.findById(decoded._id, (err, user) => {
                      if(err) {return res.send(err);}
                      if(!user){
                          return res.status(500).json({ success: false, message: 'Token owner not found.' });
                      }
      
                      //if refresh token found, and not expired, refresh expiry time
                      let isValidToken = _(user.refresh_tokens)
                                              .filter( (token) => {return token.expires>Date.now()} )
                                              .any({token: decoded.refresh_token});
                      if(!isValidToken){
                          req.user = {role: 'Guest'};
                          return next();
                      }
      
                      let newToken = signToken(decoded._id, decoded.role, decoded.refresh_token);
                      req.token = newToken;
                      req.user = decoded;
                      return next();
                  })
              } else {
                  // if everything is good, save to request for use in other routes
                  req.user = decoded;
                  return next();
              }
          });
      }
      

0 个答案:

没有答案