Simple JWT Authentication with Django REST Framework

In today’s world of web applications and APIs, security is paramount. One of the most common ways to secure APIs is through token-based authentication. JSON Web Tokens (JWT) have gained popularity due to their simplicity, compactness, and versatility. In this blog post, we’ll explore how to implement a simple JWT authentication system using Django REST Framework, along with illustrative examples.

Understanding JWT Authentication

JSON Web Tokens (JWT) are a compact, URL-safe means of representing claims between two parties. In the context of authentication, a JWT is usually issued by an authentication server when a user logs in successfully. This token is then included in subsequent requests to verify the user’s identity and access permissions. JWTs consist of three parts: a header, a payload, and a signature, all encoded in Base64.

  • Header: Contains information about how the JWT is encoded and the algorithm used for signing.
  • Payload: Contains the claims or data about the user, such as their ID, username, role, and more.
  • Signature: Created by combining the encoded header, encoded payload, and a secret key. It ensures the integrity of the token and can be used to verify its authenticity.

Setting Up Django Project

Let’s start by setting up a basic Django project with Django REST Framework.

  1. Create a Virtual Environment: Create a virtual environment to keep your project dependencies isolated.
   python3 -m venv myenv
   source myenv/bin/activate  # On Windows: myenv\Scripts\activate
  1. Install Dependencies: Install Django and Django REST Framework.
   pip install django djangorestframework djangorestframework-simplejwt
  1. Create a Django Project and App: Create a new Django project and an app within it.
   django-admin startproject myproject
   cd jwt_authentication
   python manage.py startapp myapp
  1. Configure Settings: In myproject/settings.py, add REST_FRAMEWORK and 'rest_framework_simplejwt' and 'myapp' to your INSTALLED_APPS.
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'myapp',
    'rest_framework_simplejwt',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

Implementing JWT Authentication

Now, let’s dive into implementing JWT authentication in your Django REST Framework application.

  1. Configure Authentication Classes: In myapp/views.py, set up authentication classes for your API views.
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response

class RestrictedView(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response(data={"message": "You have access to this restricted content."})
  1. URL Configuration: In myapp/urls.py, define a URL pattern for the restricted view.
from django.urls import path
from .views import RestrictedView

urlpatterns = [
    path('api/restricted/', RestrictedView.as_view(), name='restricted'),
]
  1. User Authentication: Inside your main folder myproject/urls.py. Create a view to handle user authentication and token issuance.
from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
    TokenVerifyView,
)
from rest_framework_simplejwt.views import TokenObtainPairView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls')),
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
]

Testing JWT Authentication

Now that everything is set up, let’s test the JWT authentication process.

1. Run the Server: Start the development server.

   python manage.py runserver

2. Obtain Token: Use a tool like curl or Postman to make a POST.

First, obtain an initial JWT token and a refresh token using the token endpoint as mentioned before:

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=<your_username>&password=<your_password>" http://127.0.0.1:8000/api/token/

Replace <your_username> and <your_password> with your actual username and password. This command sends a POST request with your credentials to the token endpoint and should receive a response containing the JWT token.

2. Access Restricted Content: Once you have the token, make a GET request to http://127.0.0.1:8000/api/restricted/, including the token in the Authorization header with the “Bearer” prefix.

You can use it to access restricted content by including it in the Authorization header with the “Bearer” prefix in subsequent requests. Here’s how you can make a request to the restricted endpoint using the obtained token:

curl -H "Authorization: Bearer <your_token>" http://127.0.0.1:8000/api/restricted/

Replace <your_token> with the actual JWT token you received from the previous curl command. This request should give you access to the restricted content if your token is valid and has the necessary permissions.

3. Refresh tokens: Refresh tokens are an important part of the JWT authentication process, as they allow users to obtain a new access token without having to re-enter their credentials. Here’s how you can use curl to obtain a new access token using a refresh token:

Once you have the refresh token, which you get when sending username and password, you can use it to obtain a new access token using the refresh token endpoint:

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "refresh=<your_refresh_token>" http://127.0.0.1:8000/api/token/refresh/

Replace <your_refresh_token> with the actual refresh token you obtained from the previous token request. This command will send a POST request with the refresh token to the refresh token endpoint and should receive a response containing a new access token.

Now, you can use the new access token to access restricted content as before

Remember that refresh tokens usually have a longer expiration time than access tokens, allowing them to be used to refresh the access token multiple times. This is helpful for maintaining a user’s session without requiring them to log in frequently.

Now that we have implemented Default Login view using JWT. You can take a example of how to create User Registeration from our blog which will be non restricted view. – User Registration, Login, Logout API using Django Rest Framework

Conclusion

Implementing JWT authentication in Django REST Framework is a powerful way to secure your APIs and ensure that only authorised users can access sensitive resources. By following the steps outlined in this guide, you’ve learned how to set up a simple JWT authentication system in your Django project. Remember that security is an ongoing concern, and you should consider additional security measures and best practices to protect your application and users’ data.

Find this project on Github.

Blogs You Might Like to Read!