I solved this problem by adding a variable in the token data:
softexp - I set this to 5 mins (300 seconds)
I set expiresIn
option to my desired time before the user will be forced to login again. Mine is set to 30 minutes. This must be greater than the value of softexp
.
When my client side app sends request to the server API (where token is required, eg. customer list page), the server checks whether the token submitted is still valid or not based on its original expiration (expiresIn
) value. If it's not valid, server will respond with a status particular for this error, eg. INVALID_TOKEN
.
If the token is still valid based on expiredIn
value, but it already exceeded the softexp
value, the server will respond with a separate status for this error, eg. EXPIRED_TOKEN
:
(Math.floor(Date.now() / 1000) > decoded.softexp)
On the client side, if it received EXPIRED_TOKEN
response, it should renew the token automatically by sending a renewal request to the server. This is transparent to the user and automatically being taken care of the client app.
The renewal method in the server must check if the token is still valid:
jwt.verify(token, secret, (err, decoded) => {})
The server will refuse to renew tokens if it failed the above method.