Django Rest Framework JWT is a powerful tool for securing APIs, and it's surprisingly easy to implement.
You can start by installing the required packages, including `djangorestframework` and `rest_framework_simplejwt`, using pip.
To generate a JWT token, you'll need to create a `TokenObtainPairView` in your Django app, which will handle the authentication process.
This view will return a JSON Web Token (JWT) that can be used to authenticate subsequent API requests.
The JWT token is stored in the user's session, and can be accessed using the `get_user` method of the `Token` object.
This approach provides a convenient and secure way to authenticate users and protect your API endpoints.
Django Rest Framework Installation
To install Django Rest Framework, you need to add 'rest_framework' to your project's INSTALLED_APPS in the settings.py file. This is a crucial step in enabling JWT authentication.
Django Rest Framework and Simple-JWT need to be installed in your project. You can do this by adding them to your requirements.txt or installing them directly using pip.
Django Rest Framework Installation
To get started with Django Rest Framework, you first need to install it. This involves adding 'rest_framework' to your project's INSTALLED_APPS in the settings.py file.
Django Rest Framework can be installed using pip, which is a package installer for Python. You can add it to your requirements.txt file or install it directly using pip.
You'll also need to install Simple-JWT, which is a library that provides JSON Web Token authentication. Add 'rest_framework_simplejwt' to your project's INSTALLED_APPS in the settings.py file.
By following these steps, you'll be able to enable JWT authentication in your Django project. This will provide a secure way to authenticate users and access protected resources.
Prerequisites
To install Django Rest Framework, you'll need to have some prior knowledge of HTML files and how to set up a Django project, as well as a basic understanding of what an API is.
You should already have a Django project set up, which could be named anything you like, but the example in the article uses "tokenization" and includes an app called "access".
You'll also need to import the timedelta from the datetime module before you can use it, so make sure to add that to your code.
Project Setup
To set up a project with Django Rest Framework JWT, you'll need to choose a JSON Web Token (JWT) authentication plugin. For this example, we'll use the simple JWT plugin for Django Rest Framework (DRF).
RESTful APIs are a type of web API that allow communication between different applications over the internet in a fast, reliable, and scalable way.
You'll need to install the rest_framework_simplejwt package to use the simple JWT plugin. This package provides a JSON Web Token authentication plugin for Django Rest Framework (DRF).
The simple JWT plugin is a great choice for Django Rest Framework (DRF) because it's easy to use and provides a lot of features out of the box.
Token Generation and Handling
When a user logs in, you can generate a token for them using the endpoint that returns an access token and a refresh token. This is done to provide a secure way to authenticate users.
The access token is used to authenticate the user for each request, while the refresh token is used to obtain a new access token when the original one expires. This ensures that the user remains authenticated even after a certain period of inactivity.
You can customize the token payload using a custom function specified in the JWT_PAYLOAD_HANDLER. This allows you to include additional information in the token, such as the user's profile data.
Token Generation and Handling
Generating tokens is a crucial step in the token generation and handling process. When a user logs in, you can generate a token for them using an endpoint that returns an access token and a refresh token.
To handle token refresh, you should provide an endpoint for refreshing tokens, allowing users to get a new access token using their refresh token. This endpoint should be used when a user's token is close to expiring.
You can verify a token by passing it to a verification endpoint, which will return a 200 response and the token if it's valid. If the token is invalid, it will return a 400 Bad Request with an error explaining why.
A custom function can be specified to generate the token payload using the JWT_PAYLOAD_HANDLER. This allows you to control the data included in the token.
The response data returned after login or refresh can also be customized using the JWT_RESPONSE_PAYLOAD_HANDLER. By default, it returns the JWT token, but you can override it to include additional data.
Customizing the token timelines is also possible by setting up a dictionary called SIMPLE_JWT and defining variables for the access and refresh token timelines. This allows you to control how long the tokens are valid for.
Refresh tokens can be used to obtain a brand new token with a renewed expiration time. To do this, you can pass an existing token to a refresh endpoint, which will return a new token. This process can be repeated, but it's limited by the JWT_REFRESH_EXPIRATION_DELTA setting, which determines how long after the original token that future tokens can be refreshed from.
Cookie
Cookies can be used as a valid transport for the token, in addition to the Authorization header.
You can set a string to use http cookies by setting the JWT_AUTH_COOKIE variable. This string will be used as the cookie name that will be set in the response headers when requesting a token.
The token validation procedure will look into this cookie if it's set, but the 'Authorization' header takes precedence if both are present in the request.
By default, no cookie is set when creating tokens, and none are accepted when validating them.
Secret Key
The secret key is a crucial component in token generation and handling. It's used to sign the JWT, making it secure and tamper-proof.
The default secret key is your project's settings.SECRET_KEY, but this shouldn't be shared or made public, as it compromises the security of your tokens.
However, having a secret key per user, as provided by JWT_GET_USER_SECRET_KEY, offers an extra layer of security. This way, in case a token is compromised, the owner can easily change their secret key, making all tokens for that user unusable.
This function should return a secret key for a given user, accepting the user as the only parameter.
Security
When using JWTs in Django Rest Framework, security is a top priority. Unlike some other uses of JWTs, this module only generates authentication tokens that verify the user requesting a protected API resource.
You should only expose your API endpoints over SSL/TLS to protect against content tampering and certain kinds of replay attacks. This is because the actual request parameters themselves are not included in the JWT claims, making them vulnerable to tampering.
JWTs are essential for protecting the integrity of information, especially when using public-private key pairs to compute signatures. This ensures that the payload and header are secure.
Signing JWTs with public-private key pairs makes sure that the information is not compromised, which is crucial for exchanging sensitive data.
Customizing and Extending
You can customize how JWT authentication works in your application to suit your business needs better. For example, you might want to increase or decrease the Access and Refresh token expiration time, or want the ability to also refresh the refresh token.
The SIMPLE_JWT setting allows you to customize this behavior. You can define it in your settings to change the default behavior.
To extend JSONWebTokenAuthentication, you can write a custom Authentication class. It's recommended to use BaseJSONWebTokenAuthentication, a new base class with no logic around parsing the HTTP headers.
Customizing the token timelines involves creating a dictionary called SIMPLE_JWT and setting up variables to hold timelines for the access and refresh token.
To use JWT authentication, you’ll need a user authentication system. You can use Django’s built-in User model or create a custom user model.
You can specify a custom function to generate the token payload using JWT_PAYLOAD_HANDLER. This is useful when you need to include additional information in the token payload.
The JWT_RESPONSE_PAYLOAD_HANDLER is responsible for controlling the response data returned after login or refresh. By default, it returns the JWT token, but you can override it to return a custom response.
Understanding JWT
JWT, or JSON Web Token, is a compact and self-contained method for securely transmitting information between parties as a JSON object.
JWTs consist of three parts: Header, Payload, and Signature. The Header contains information about how the JWT is signed, the Payload contains the claims and additional data, and the Signature is used to verify the authenticity of the token.
Here's an example of how JWTs work: a JWT is an authorization token that is included in requests, and it can be obtained by logging in with a username and password. The server returns an access and refresh token in the form of a JWT.
The lifetimes of access and refresh tokens vary, with access tokens lasting for five minutes or less and refresh tokens lasting for 24 hours.
How They Work
A JWT is an authorization token that's included in requests, and it's generated when you log in with your username and password. The server returns an access and refresh token in the form of a JWT.
The access token lasts for five minutes or less, while the refresh token can last for 24 hours. This is to prevent damage that can occur when a token is compromised and to prevent unauthorized access.
If the access token expires, the client uses the refresh token to summon a new access token from the server. Once the refresh token expires, the user must log in again with their username and password to get a new pair of tokens.
Here's a breakdown of how JWTs work:
The client stores the JWT securely, such as in a cookie or local storage, and sends it with each request to protected resources. The server verifies the JWT's signature and grants access to the requested resource if the token is valid.
Payload Handler
The payload handler is a crucial part of the JWT process. It determines what data is included in the token.
You can specify a custom function to generate the token payload, as seen in Example 3, "JWT_PAYLOAD_HANDLER". This allows you to include specific information that's relevant to your application.
The default payload handler includes the username, but if you store it differently, you can implement a custom function to fetch it, as shown in Example 5, "JWT_PAYLOAD_GET_USERNAME_HANDLER".
If you need to control the response data returned after login or refresh, you can override the default response payload handler, found in Example 4, "JWT_RESPONSE_PAYLOAD_HANDLER". This allows you to return a custom response, such as including the serialized representation of the User.
Remember, the payload handler is where you can get creative with the data included in your JWT token.
Algorithm
The algorithm used in JWT authentication is crucial for its security. JWT uses a compact and self-contained method for securely transmitting information, and the algorithm plays a vital role in this process.
The JWT algorithm is used to sign the JWT, ensuring its authenticity. This is done using a secret key, which is a fundamental aspect of the JWT algorithm.
The default algorithm used in PyJWT is HS256. This is a commonly used algorithm for cryptographic signing.
You can specify a custom algorithm when generating a JWT, but HS256 is the default and most widely used option.
Leeway
Leeway is a feature that allows for some flexibility in validating JWT expiration times.
You can set a leeway to give yourself some margin in case the JWT is processed slightly after its expiration time. For example, if you set a leeway of 10 seconds, a JWT with an expiration time 30 seconds after creation can still be validated 10 seconds later.
The default leeway is 0 seconds, which means no margin is given.
Without a leeway, you risk having JWTs that are too sensitive to timing issues, which can lead to unexpected behavior.
By setting a leeway, you can ensure that your JWT validation is more robust and less prone to errors.
Expiration
Expiration is a crucial aspect of JWTs, and it's essential to understand how it works. JWTs have two types of tokens: access tokens and refresh tokens.
Access tokens typically last for five minutes or less, but you can customize this timeline. The refresh token, on the other hand, can last for 24 hours or more, depending on your configuration.
If an access token expires, the client uses the refresh token to get a new access token from the server. This process prevents damage if a token is compromised and unauthorized access.
You can also set a leeway of a few seconds to account for processing delays. For example, if a token expires 30 seconds after creation, you can set a leeway of 10 seconds to give yourself some margin.
However, be aware that if you turn off expiration time verification, JWTs will last forever, which can be a security risk. This is why it's essential to verify expiration times to prevent leaked tokens from being used indefinitely.
The default expiration time is 5 minutes, but you can customize this to suit your needs. You can also set a limit on token refresh, which is the maximum amount of time after the original token that future tokens can be refreshed from.
Sources
- https://www.remoteinning.com/blog/how-to-use-jwt-authentication-with-django-rest-framework
- https://blog.devgenius.io/jwt-authentication-in-django-rest-framework-with-simple-jwt-a-comprehensive-guide-f2ba860f1365
- https://jpadilla.github.io/django-rest-framework-jwt/
- https://www.freecodecamp.org/news/how-to-use-jwt-and-django-rest-framework-to-get-tokens/
- https://medium.com/@calebjephuneh/implementing-simple-jwt-authentication-in-django-rest-framework-029d8f6468b5
Featured Images: pexels.com