Django REST APIs with JWT Authentication using dj-rest-auth
What is JWT Authentication?
JWT (JSON Web Token) authentication is a method for securely transmitting information between parties as a JSON object. It is commonly used in web development to authenticate users and provide secure access to protected resources.
Getting started
In this tutorial, we will be setting up a Django project, exposing an API using the Django REST framework (DRF), and securing its endpoint using JWT authentication.
- Second part: User sign up over API
- This part: Sign in with Google to access your API
Step 1 — Install required packages
# requirements.txt
Django==5.0.6
djangorestframework==3.15.2
djangorestframework-simplejwt==5.3.1 # JWT token implementation for DRF
dj-rest-auth==6.0.0 # REST API authentication utils
You can see that we’re using a package called dj-rest-auth
. This module provides a set of REST API endpoints to handle user registration and authentication tasks.
Step 2 — Basis setup
Add this to your settings.py
INSTALLED_APPS = [
...,
'rest_framework',
'rest_framework.authtoken',
'dj_rest_auth'
]
Usage of rest_framework.authtoken
requires us to migrate the database
python manage.py migrate
Set the default authentication class for DRF views
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
)
...
}
Configure dj-rest-auth
and djangorestframework-simplejwt
from datetime import timedelta
# djangorestframework-simplejwt
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(hours=1),
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
}
# dj-rest-auth
REST_AUTH = {
"USE_JWT": True,
"JWT_AUTH_COOKIE": "_auth", # Name of access token cookie
"JWT_AUTH_REFRESH_COOKIE": "_refresh", # Name of refresh token cookie
"JWT_AUTH_HTTPONLY": False, # Makes sure refresh token is sent
}
Full list of dj-rest-auth’s settings and djangorestframework-simplejwt’s settings
Expose authentication endpoints in urls.py
urlpatterns = [
path("admin/", admin.site.urls),
path("api/v1/auth/", include("dj_rest_auth.urls")),
...
]
Step 3— Testing the authentication
First, make sure we have a user we can test with.
python manage.py createsuperuser
Now, using the HTTP client of your choice (Postman, Insomnia, CURL), check the user’s session by making a GET request to /api/v1/auth/user/
As you can see, currently we are not signed in, and we received an HTTP 401 Unauthorized response.
In order to sign in, call the /api/v1/auth/login/
endpoint, providing your user credentials.
Keep in mind that besides an access token, refresh token, and user details in the response, dj-rest-auth
will also set the _auth
and _refresh
cookies on the client.
If you retry the api/v1/auth/user/
call now (assuming your HTTP client will attach the cookies, which happens by default in clients like Postman or Insomnia), you will get a successful response.
Step 4 — Available endpoints
Here’s a list of all currently available endpoints. We can see the endpoints we already tried: /user
and /login
, but also the/token/refresh
endpoint that we can call to prolong our session or the /logout
endpoint to clear the user’s session.
There are also three endpoints connected to password resetting, but those require additional setup of email sending and might not work out of the box.
/api/v1/auth/login/ dj_rest_auth.views.LoginView rest_login
/api/v1/auth/logout/ dj_rest_auth.views.LogoutView rest_logout
/api/v1/auth/password/change/ dj_rest_auth.views.PasswordChangeView rest_password_change
/api/v1/auth/password/reset/ dj_rest_auth.views.PasswordResetView rest_password_reset
/api/v1/auth/password/reset/confirm/ dj_rest_auth.views.PasswordResetConfirmView rest_password_reset_confirm
/api/v1/auth/token/refresh/ dj_rest_auth.jwt_auth.RefreshViewWithCookieSupport token_refresh
/api/v1/auth/token/verify/ rest_framework_simplejwt.views.TokenVerifyView token_verify
/api/v1/auth/user/ dj_rest_auth.views.UserDetailsView rest_user_details
Refreshing access token
Inside settings.py
, we set how long both the access and refresh tokens should be valid. A good practice is to keep the access token lifetime short and refresh it when needed.
If you need to refresh the expired access token, you can use the /api/v1/auth/token/refresh/
endpoint.
Step 5 — Authorization Header vs. Cookie (optional)
Current implementation returns the access token and refresh token as part of the HTTP response body as well as inside the set-cookie
HTTP header. That way, we don’t need to manually attach the authentication credentials (cookies) on every call.
This is very convenient but not always desired. If you do not want to use cookie sessions, you can pass the access token inside the Authorization
header.
Here’s a quick guide on how to do that:
Let’s call the login endpoint and grab the access token.
Now, let’s clear the cookies from our HTTP client and check the user’s session.
As expected, we don’t have any cookies; therefore, Django couldn’t match any user to our request.
Now, let’s attach the Authorization
header to our request and give it a value of Bearer <access_token>
This time, the user was recognized correctly.
Cleanup
Optionally, you can allow users to authenticate only via the Authorization
header by slightly changing the settings.
First, add djangorestframework-simplejwt
to INSTALLED_APPS.
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken',
'rest_framework_simplejwt',
'dj_rest_auth'
]
Next, change the default authentication class for Django REST framework.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
Lastly, you can disable cookies from being sent in the response by removing these two settings from REST_AUTH.
REST_AUTH = {
"USE_JWT": True,
# "JWT_AUTH_COOKIE": "_auth", # Don't send access token cookie
# "JWT_AUTH_REFRESH_COOKIE": "_refresh", # Don't send refresh token cookie
"JWT_AUTH_HTTPONLY": False, # Makes sure refresh token is sent
}
Conclusion
In this tutorial, we used dj-rest-auth
to expose API endpoints that allow you to obtain JWT tokens for our users, validate the session, refresh the access token, and clear the session by logging out.
Code Repository
Example code from this tutorial is available in my GitHub repository:
https://github.com/Mich0232/drf-jwt-tutorial
Further reading
I’m working on a continuation of this tutorial to cover additional topics related to JWT authentication in Django REST framework. I’ll make sure to link them here once they are available.
- Second part: User registration support
- Third part: Social provider authentication (Google, etc.)
Thank you for reading!