JWT Authentication in Django


JSON Web Token (JWT) is a compact and self-contained way of securely transmitting information between the client and server as a JSON object. JWTs are commonly used in modern web applications for authentication and authorization. In this article, we will learn how to implement JWT authentication in a Django application using the Django Rest Framework (DRF) and the djangorestframework-simplejwt package.

1. What is JWT?

JWT is a standard for securely transmitting information as a JSON object. It is composed of three parts:

  • Header: Contains information about how the token is signed (e.g., the algorithm used).
  • Payload: Contains the claims or information you want to transmit (e.g., user data).
  • Signature: Used to verify that the sender is who it claims to be and to ensure the message wasn't changed along the way.

JWTs are stateless and self-contained, which makes them perfect for API authentication in distributed systems. With JWT, the server doesn't need to store session data, as everything needed to authenticate the user is encoded in the token itself.

2. Installing Required Packages

To implement JWT authentication in Django, we need to install the djangorestframework and djangorestframework-simplejwt packages. Use the following commands to install them:

            
    pip install djangorestframework
    pip install djangorestframework-simplejwt
            
        

Once installed, add these packages to your INSTALLED_APPS in settings.py:

            
    # settings.py
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework',  # Django Rest Framework
        'rest_framework_simplejwt',  # SimpleJWT for JWT Authentication
    ]
            
        

3. Setting Up JWT Authentication in Django

To use JWT authentication in Django, we need to update the REST_FRAMEWORK settings in the settings.py file. We will specify JWTAuthentication as the authentication class.

            
    # settings.py
    from datetime import timedelta

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_simplejwt.authentication.JWTAuthentication',  # Enable JWT Authentication
        ],
    }

    # JWT Settings (Optional)
    SIMPLE_JWT = {
        'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),  # Access token expiration time
        'REFRESH_TOKEN_LIFETIME': timedelta(days=1),  # Refresh token expiration time
        'ROTATE_REFRESH_TOKENS': False,  # Whether to rotate refresh tokens
        'BLACKLIST_AFTER_ROTATION': False,  # Whether to blacklist old refresh tokens
    }
            
        

The ACCESS_TOKEN_LIFETIME and REFRESH_TOKEN_LIFETIME settings control how long the access and refresh tokens are valid. You can adjust these based on your application’s requirements.

4. Creating Token Views

Next, we need to create views that will handle generating and refreshing the JWT tokens. The djangorestframework-simplejwt package provides built-in views for obtaining and refreshing tokens.

Obtaining JWT Access and Refresh Tokens

To obtain a JWT access token, we use the TokenObtainPairView view. This view takes the user’s credentials (username and password) and returns a pair of tokens: an access token and a refresh token. The access token is used to authenticate requests, and the refresh token can be used to generate a new access token after it expires.

            
    # urls.py
    from django.urls import path
    from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView

    urlpatterns = [
        path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),  # Get JWT token
        path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),  # Refresh JWT token
    ]
            
        

The TokenObtainPairView is a built-in view that handles obtaining the JWT pair, while the TokenRefreshView handles refreshing the access token using the refresh token.

Example: Requesting Tokens

To obtain the JWT tokens, send a POST request to the /api/token/ endpoint with the username and password:

            
    curl -X POST -d "username=myuser&password=mypassword" http://127.0.0.1:8000/api/token/
            
        

If the credentials are correct, the server will return a response containing both the access token and the refresh token:

            
    {
        "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHBpcnkiOjE2MzE4MDEwMzQsIn0.9b6_xGgLM30TqLjOX8kp5a-VfgFfWpnmHtqjXjL4n3g",
        "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHBpcnkiOjE2MzE4MDEwMzQsIn0.GqV6VqJf_XMc_LPZP7ccowkDtwPmnGfEqO2RfZd0L6k"
    }
            
        

5. Using JWT for Authentication in API Views

Once the user has obtained the access token, they can include it in the Authorization header for authentication in subsequent requests. The token is passed as a Bearer token in the header.

            
    Authorization: Bearer 
            
        

Example: Protecting API Views with JWT Authentication

Now, let’s create an API view that is protected by JWT authentication. We will use the IsAuthenticated permission class to ensure that only authenticated users can access the view.

            
    # views.py
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.views import APIView
    from rest_framework.response import Response

    class UserProfileView(APIView):
        permission_classes = [IsAuthenticated]  # Only authenticated users can access this view

        def get(self, request):
            content = {'message': f'Hello, {request.user.username}'}
            return Response(content)
            
        

This view checks if the user is authenticated. If the request includes a valid access token, the view will return a personalized message containing the user's username.

6. Refreshing JWT Tokens

JWT tokens have a limited lifespan, and after they expire, the client must obtain a new one. The refresh token, however, can be used to obtain a new access token without requiring the user to log in again.

To refresh the access token, send a POST request to the /api/token/refresh/ endpoint with the refresh token:

            
    curl -X POST -d "refresh=" http://127.0.0.1:8000/api/token/refresh/
            
        

If the refresh token is valid, the response will include a new access token:

            
    {
        "access": "new-access-token"
    }
            
        

7. Conclusion

In this article, we explored how to set up JWT authentication in Django using Django Rest Framework and the djangorestframework-simplejwt package. JWT is a secure and stateless authentication method that is widely used in modern web applications. By using JWT, you can ensure secure communication between the client and the server while keeping your API scalable and easy to maintain.





Advertisement