26

I am making API Server with Node.js and Express.

Also I used JWT token authentication for auth user.

If token is expired, my scenario is here.

  1. (Backend) Middleware detect expired

  2. (Frontend) Receive token is expired

  3. (Fronend) Refresh token request to backend

  4. (Backend) Verify token is valid and if it expired, sign new token(with old token's payload) and response it to frontend

at number 4, my code is here.

try {
    const token = req.headers.authorization.split(' ')[1];
    jwt.verify(token, SECRET, (err, decoded) => {
        if(err.name === 'TokenExpiredError') {
            const payload = jwt.verify(token, SECRET);
            const userid = payload.userid;
            const is_admin = payload.is_admin;

            const refreshToken = jwt.sign({
                userid: userid,
                is_admin: is_admin
            }, SECRET, {
                algorithm: 'HS256',
                expiresIn: '10m'
            })
            res.status(200).json({status: true, token: refreshToken});
        }
        else if(err) {
            res.status(401).json({status: false, result: "Invalid token"});
        }
    })
} catch(e) {
    //console.log(e);
    res.status(401).json({status: false, result: "Token does not exist"});
}

After run it, throw errors line of const payload = jwt.verify(token, SECRET);.

Because if token is expired, it throws TokenExpiredError error.

I want to decode token and extract payload of expired token.

But in verify(), there is no information about payload.

So I read document, found some interest method decode().

But it mention that do not use decode(), because it doesn't check signature is correct or not.

Is there any solution about extract payload of expired token?

Thanks.

Hide
  • 3,199
  • 7
  • 41
  • 83

1 Answers1

55

You can set the option ignoreExpiration to true to avoid getting this error for expired tokens (at that point you know it already) and then get the payload:

if(err.name === 'TokenExpiredError') {
    const payload = jwt.verify(token, SECRET, {ignoreExpiration: true} );
    // your code
}

Now you can be sure the token is valid but just expired.

jps
  • 20,041
  • 15
  • 75
  • 79
  • 1
    Just out of curious, if I can get the payload using ignoreExpiration, what is the use of setting expiry time for the JWT.. – Shen Prabu Jul 23 '21 at 06:01
  • @ShenPrabu i had the same question in mind, but i think to give access to check or to get info hidden in token for example in my case to get back the user name when firing logout button and avoid returning error while token expired. – Salah ED Oct 24 '21 at 13:20
  • 1
    @ShenPrabu The contents of the JWT should not be something private. I like this metphor: "A man riding a horse arrives to town, and tells everyone the king wants X amount of gold from all of them. A vilager rose and said 'I can verify if the king really said that'". In this case, the message is "give me gold", it's not a password, or something very sensitive. It's a message that I dont care if others read. All I care about is veryfing that the king ACTUALLY wrote/signed that letter. So yeah, the client can say `{ignoreExpiration:true}`, but clearly the server would not, and that's what counts. – Tal Kohavy Oct 18 '22 at 22:15