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

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

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

    如果上面的描述是正确的,那么将刷新标记作为已签名的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令牌:

  • 同上
  • 同上
  • 同上
  • 当jwt令牌过期时,服务器从jwt令牌中挑选刷新令牌并检查它是否存在于数据库中,并且它未到期。
  • 服务器响应所请求的资源+新的jwt令牌。
  • 客户端会在响应中看到新的令牌并将其保存以供进一步的请求使用。
  • 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();
            }
        });
    }
    
    链接地址: http://www.djcxy.com/p/22033.html

    上一篇: Signing jwt token with refresh token as payload

    下一篇: Log out user after inactivity with JWT Access and Refresh tokens