Skip to main content

Logout and Token Blacklisting

We can say a user is logged in when they send us a valid JWT.

The iss field in that JWT contains the user's identity (in the case of our application, that's an user id field).

To perform logout in a simple way, we can revoke individual JWTs so that even if it is sent to us and is valid, it cannot be used. Even if the JWT was somehow stolen from the user's browser, it could still not be used.

Revoking tokens in our application simply means placing them on a blacklist. Before processing a token, we check whether it is in the blacklist. If it is, we do not process it and instead return a message saying "this token has been revoked".

This achieves everything we want from a log out:

  • Users can not use the token to access protected resources (because they're logged out).
  • Users need to log in again (and get a new token) if they want to be "logged in".
  • The token cannot be used again even if it is lost or stolen.

In our application, the file blacklist.py contains an (initially empty) set of unique JWT identifiers that are blacklisted.

The blacklist.py file:

"""
blacklist.py

This file just contains the blacklist of the JWT tokens–it will be imported by
app and the logout resource so that tokens can be added to the blacklist when the
user logs out.
"""

BLACKLIST = set()

When we want to log a user out, we add the JWT that they're currently using to the blacklist, in the UserLogout resource:

class UserLogout(Resource):
@jwt_required
def post(self):
jti = get_raw_jwt()["jti"] # jti is "JWT ID", a unique identifier for a JWT.
user_id = get_jwt_identity()
BLACKLIST.add(jti)
return {"message": "User <id={}> successfully logged out.".format(user_id)}, 200

That's really all there is to it in this simple implementation.

Now there is something to take into account, however...

Caveat

This blacklist is not saved to a database, so if your application crashes or your server needs to restart, the blacklist is emptied.

All previously used tokens can now be used again, so all "logged out" users that still have access to their JWT will continue to be able to log in.

Unless the JWT has expired already, which is most likely has done since they only last a small amount of time.

It is nonetheless something to keep into consideration, and while not covered in the Advanced REST API course, an even more advanced course might include saving this blacklist into a database such as Redis.