I've read a lot about JWT and how to create "stateless" sessions through JWT. The gist of what I understand is that because of the signature & expiration, you can essentially send the entire session to be saved by the client and the server does not have to maintain a db to remember the session.
What I do not understand is what happens if your user needs to log out, or you need to invalidate a session before the expiration?
Technically, you could instruct the browser to delete it from the client side, but you can't be sure this actually occurred. The token itself is technically still valid and if your deletion instructions weren't followed, it could still be used.
Is this understanding correct? If so, isn't this a huge fault with client-side session management? Are there any methods to overcoming this aside from having the server store the session or making the expiration time short?
Once they're logged out, we can let the JWT token expire, and invalidate it. That being said, we'll need to map a device as well as the refresh token to a user's session. Since we've got a mechanism to identify devices - let's implement the functionality to map a user device to a user login session.
New jwt tokens would set their version to this. When you validate the jwt, simply check that it has a version number equal to the users current jwt version. Any time you want to invalidate old jwts, just bump the users jwt version number.
Bottom line. Although JWT does eliminate the database lookup, it introduces security issues and other complexities while doing so. Security is binary—either it's secure or it's not. Thus making it dangerous to use JWT for user sessions.
But if you really want to invalidate it immediately, you would need a few things: Cache the token's ID once the token is created with a duration as long as the expiration time of the token (both, access and refresh token) [If Farm/multiple instances]You need to cache it in a distributed cache, like redis.
There are several reason to invalidate a JWT token before its expiration time: account deleted/blocked/suspended, password changed, permissions changed, user logged out by admin. So your question is on topic
There are several techniques to apply or combine depending on your use case
1) Remove the client token from local storage
2) Token blacklist: Store tokens that were between logout & expiry time, mark expired and check it in every request. Use a unique identifier jti
or include last login date and issued at iat
to remove old tokens
It is needed server storage. If you do not expect too many tokens to revoke, you also could use an in-memory blacklist. You only need to set an entry after updating critical data on user and currentTime - maxExpiryTime < lastLoginDate (iat)
. The entry can be discarded when currentTime - maxExpiryTime > lastModified
(no more non-expired tokens sent). In this case is not needed to store the entire token. Just sub
, iat
and maybe jti
3) Expiry times short and rotate them. Issue a new access token every few request. Use refresh tokens to allow your application to obtain new access tokens without needing to re-authenticate and combine with sliding-sessions
Sliding-sessions are sessions that expire after a period of inactivity. When a user performs an action, a new access token is issued. If the user uses an expired access token, the session is considered inactive and a new access token is required. This new token can be obtained with a refresh token or requiring credentials
Allow change user unique ID if account is compromised with a new user&password login
To invalidate tokens when user changes their password, sign the token with a hash of their password. If the password changes, any previous tokens automatically fail to verify. Extend this mechanism with other field of interest to sign. The downside is that it requires access to the database
Change signature algorithm to revoke all current tokens in major security issues
Take a look at Invalidating JSON Web Tokens
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With