JWT Logout — Django Rest Framework
Build a Product Review Backend with DRF — Part 10
When using JWT authentication, the client side stores the token and attaches it to every request. So, the first thing to do when logging out, is just delete the token you stored on local storage. In that case the client won’t have a token to put in the request, thus causing unauthorized response status. But this is not enough. the token still exists somewhere and it is still valid. It’s not that simple with JWT. It is not possible to forcefully delete or invalidate an existing token. The tokens can be expired but you can’t do it on demand.
JWT should be stateless, you should store everything in the payload and skip performing a DB query on every request. But you might need to some queries for logout functionality. If you really must have log out functionality, then you can use a black list. You still have to lookup the token on every request to be sure it is still valid.
Simple JWT includes an app that provides token blacklist functionality. To use this app, include it in your list of installed apps in settings.py:
Also, make sure to run python manage.py migrate to run the app’s migrations.
$ python manage.py makemigrations...Running migrations:
Applying token_blacklist.0001_initial… OK
Applying token_blacklist.0002_outstandingtoken_jti_hex… OK
Applying token_blacklist.0003_auto_20171017_2007… OK
Applying token_blacklist.0004_auto_20171017_2013… OK
Applying token_blacklist.0005_remove_outstandingtoken_jti… OK
Applying token_blacklist.0006_auto_20171017_2113… OK
Applying token_blacklist.0007_auto_20171017_2214… OK
Simple JWT will add any generated refresh or sliding tokens to a list of outstanding tokens. It will also check that any refresh or sliding token does not appear in a blacklist of tokens before it considers it as valid.
The Simple JWT blacklist app implements its outstanding and blacklisted token lists using two models: OutstandingToken and BlacklistedToken. Model admins are defined for both of these models.
The blacklist app also provides a management command, flushexpiredtokens, which will delete any tokens from the outstanding list and blacklist that have expired. You should set up a cron job on your server or hosting platform which runs this command daily.
ROTATE_REFRESH_TOKENS : When set to True, if a refresh token is submitted to the TokenRefreshView, a new refresh token will be returned along with the new access token.
BLACKLIST_AFTER_ROTATION :When set to True, causes refresh tokens submitted to the TokenRefreshView to be added to the blacklist if the blacklist app is in use and the ROTATE_REFRESH_TOKENS setting is set to True.
We previously changed the token obtain url to add custom claim. But blacklist app not compatible with custom claim. For this reason, we’ll change urls.py and we’ll use default views. Open auth/urls.py and change with below.
If you want you can delete MyTokenObtainPairSerializer (auth/serializers.py) and MyObtainTokenPairView (auth/views.py).
For logout we need to create new view. Open auth/views.py and type the following lines of code:
Open auth/urls.py and add logout endpoint:
Let’s look at the possibilities
Scenario 1:
SIMPLE_JWT = {
'REFRESH_TOKEN_LIFETIME': timedelta(days=15),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': True
}|------------|-----------------------------------------------------|
| ACTION | DESCRIPTION |
|------------|-----------------------------------------------------|
| LOGIN | - Refresh token is added automaticaly to |
| | outstanding tokens |
|------------|-----------------------------------------------------|
| LOGOUT | - You should add refresh token to the blacklisted |
| | tokens manually. |
|------------|-----------------------------------------------------|
| REFRESH | - Old refresh token is added automaticaly to |
| | blacklisted tokens. |
| | - You should add new refresh token to the |
| | outstanding tokens |
|------------|-----------------------------------------------------|
LOGIN (POST /auth/login/)
REFRESH (POST /auth/login/refresh/)
LOGOUT WITH REFRESHED TOKEN (POST /auth/logout/)
Scenario 2:
SIMPLE_JWT = {
'REFRESH_TOKEN_LIFETIME': timedelta(days=15),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': False
}|------------|-----------------------------------------------------|
| ACTION | DESCRIPTION |
|------------|-----------------------------------------------------|
| LOGIN | - Refresh token is added automaticaly to |
| | outstanding tokens |
|------------|-----------------------------------------------------|
| LOGOUT | - You should add refresh tokens to the blacklisted |
| | tokens manually. |
|------------|-----------------------------------------------------|
| REFRESH | - You should add old refresh token to the |
| | blacklisted tokens manually. |
| | - You should add new refresh token to the |
| | outstanding tokens |
|------------|-----------------------------------------------------|
LOGIN (POST /auth/login/)
REFRESH (POST /auth/login/refresh/)
LOGOUT WITH REFRESHED TOKEN (POST /auth/logout/)
Scenario 3:
SIMPLE_JWT = {
'REFRESH_TOKEN_LIFETIME': timedelta(days=15),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': False
}|------------|-----------------------------------------------------|
| ACTION | DESCRIPTION |
|------------|-----------------------------------------------------|
| LOGIN | - Refresh token is added automaticaly to |
| | outstanding tokens |
|------------|-----------------------------------------------------|
| LOGOUT | - You should add refresh token to the blacklisted |
| | tokens manually. |
|------------|-----------------------------------------------------|
| REFRESH | - No actions needed |
|------------|-----------------------------------------------------|
LOGIN (POST /auth/login/)
REFRESH (POST /auth/login/refresh/)
LOGOUT (POST /auth/logout/)
LOGOUT FROM ALL COMPUTERS
For this, we need to add all tokens belonging to the user to the black list. For Scenario 1 and Scenario 2, we need to add refreshed tokens to the outstanding list and black list also. But Scenario 3 we have only one refresh token and it is added to the outstanding list when the user logs in.
Open auth/views.py and type the following lines of code:
Open auth/urls.py and add logout_all endpoint:
When we look at our tokens before logging out, we see that there is one in the blacklist and 6 in the outstanding list.
We should send a POST request to API for checking logout_all endpoint.
As you can see all tokens have been added to the blacklist.
You can download part 10 files from
If you want to learn more about Django, do check out the documentation, django rest framework website and make sure to check out parts of this series!