Signing jwt token with refresh token as payload

How I understand jwt based authentication should work:

  • Client sends log-in credentials to server.
  • Server verifies if credentials are correct and responds with a signed jwt token and a refresh token, while also storing the refresh token in database.
  • Client uses jwt token as a Authentication header in all requests.
  • When the jwt token has expired, server responds with 401 Unauthorized .
  • Client sends a request to refresh the jwt token with the refresh token in the Authentication header.
  • Server check if the refresh token exists in database and that it has not expired. Then responds with a new jwt token
  • Client can continue requesting with the new token.
  • How I want to implement it:

    If the desciption above is correct, is there anything wrong with putting the refresh token as payload for the signed jwt token?:

    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
            }
        );
    }
    

    And in that way always sending both the refresh token and jwt token in every request? By doing this, the client would not have to send a seperate request with the refresh token to get a new jwt token:

  • Same as above
  • Same as above
  • Same as above
  • When the jwt token has expired, the server picks out the refresh token from the jwt token and checks if it exists in database and that it is not expired.
  • Server responds with the requesed resource + a new jwt token.
  • Client sees that there is a new token in the response and saves it for further requests.
  • Auth middleware would look something like this:

    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/22034.html

    上一篇: REST和身份验证变体

    下一篇: 用刷新令牌签署jwt令牌作为有效负载