Logout Django Rest Framework JWT
Every JWT which you issue should have an expiry datetime, so whenever you are logging out the user you should delete the jwt-token from the localstorage cookie.
but the token remains available.
Not sure what the above line means but you should not worry about if the token remains available to the user or not after you clear it from localstorage and cookie because either way it would get invalid after the expiry date.
You are right, even after you remove the JWT token it remains valid token for a period of time until it expires. JWT is stateless. So if you want to handle logout and to invalidate token you must need to keep a database or in memory cache to store the invalid(blacklisted) token. Then you need to add a new permission to check whether the token is blacklisted or not.
class BlackListedToken(models.Model):
token = models.CharField(max_length=500)
user = models.ForeignKey(User, related_name="token_user", on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
unique_together = ("token", "user")
class IsTokenValid(BasePermission):
def has_permission(self, request, view):
user_id = request.user.id
is_allowed_user = True
token = request.auth.decode("utf-8")
try:
is_blackListed = BlackListedToken.objects.get(user=user_id, token=token)
if is_blackListed:
is_allowed_user = False
except BlackListedToken.DoesNotExist:
is_allowed_user = True
return is_allowed_user
You can remove the token from the blacklisted list after its expiry.
You cannot manually expire a token after it has been created. Thus, you cannot actually log out with JWT on the server side as you do with sessions.
JWT is stateless, meaning that you should store everything you need in the payload and skip performing a DB query on every request. But if you plan to have a strict log out functionality, that cannot wait for the token auto-expiration, even though you have cleaned the token from the client-side, then you might need to neglect the stateless logic and do some queries. so what's a solution?
Set a reasonable expiration time on tokens
Delete the stored token from client-side upon log out
Query provided token against The Blacklist on every authorized request
The Blacklist
“Blacklist” of all the tokens that are valid no more and have not expired yet. You can use a DB that has TTL option on documents that would be set to the amount of time left until the token is expired.
Redis
Redis is a good option for blacklist, which will allow fast in-memory access to the list. Then, in the middleware of some kind that runs on every authorized request, you should check if the provided token is in The Blacklist. If it is you should throw an unauthorized error. And if it is not, let it go and the JWT verification will handle it and identify if it is expired or still active.
For more information, see How to log out when using JWT. by Arpy Vanyan