- Published at
Django Ninja JWT Integration Guide
Integrate Django Ninja JWT for secure API authentication. Learn to install, configure, and use JWT endpoints with custom controllers and localization.
- Authors
-
-
- Name
- James Lau
- Indie App Developer at Self-employed
-
Table of Contents
This blog post guides you on integrating Django Ninja JWT into your Django Ninja project for robust authentication.
Installation
First, install the django-ninja-jwt package using pip:
pip install django-ninja-jwt
Configuration
- Register the Controller:
In your api.py file, register the NinjaJWTDefaultController to enable the default JWT endpoints.
from ninja_jwt.controller import NinjaJWTDefaultController
from ninja_extra import NinjaExtraAPI
api = NinjaExtraAPI()
api.register_controllers(NinjaJWTDefaultController)
- Custom Controllers (Optional):
You can create custom controllers inheriting from TokenObtainPairController to manage token retrieval and refresh.
from ninja_extra import api_controller
from ninja_jwt.controller import TokenObtainPairController
@api_controller('token', tags=['Auth'])
class MyCustomController(TokenObtainPairController):
"""obtain_token and refresh_token only"""
...
api.register_controllers(MyCustomController)
This example creates a controller under the “token” path, allowing you to customize authentication logic while leveraging the built-in JWT functionality.
- Localization (Optional):
To enable translations, add ninja_jwt to your INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
...
'ninja_jwt',
...
]
Usage Examples
Here’s how to interact with the JWT endpoints using curl.
- Obtain Token Pair:
This request retrieves both an access token and a refresh token. Replace `
curl -X POST http://your-api-url/token/obtain/ \
-H "Content-Type: application/json" \
-d '{"username": "your_username", "password": "your_password"}'
The response will include an access token (short-lived, used for authenticated requests) and a refresh token (long-lived, used to obtain new access tokens):
{
"access": "your_access_token",
"refresh": "your_refresh_token"
}
- Refresh Token:
To obtain a new access token using the refresh token:
curl -X POST http://your-api-url/token/refresh/ \
-H "Content-Type: application/json" \
-d '{"refresh": "your_refresh_token"}'
The response will provide a new access token:
{
"access": "new_access_token"
}
- Using the Access Token:
Use the access token to authenticate API requests by including it in the Authorization header:
curl -X GET http://your-api-url/protected-endpoint/ \
-H "Authorization: Bearer your_access_token"
Customizing Authentication Logic
You can extend the TokenObtainPairController to add custom validation or additional fields to the token response. For example:
from ninja import Schema
from ninja_jwt.controller import TokenObtainPairController
from ninja_extra import api_controller, route
class CustomTokenResponse(Schema):
access: str
refresh: str
user_id: int
@api_controller('token', tags=['Auth'])
class MyCustomController(TokenObtainPairController):
@route.post("/obtain", response=CustomTokenResponse)
def obtain_token(self, request, *args, **kwargs):
response = super().obtain_token(request, *args, **kwargs)
return {
"access": response["access"],
"refresh": response["refresh"],
"user_id": request.user.id
}
This custom controller adds the user_id to the token response, which can be useful for client-side applications.
Securing Endpoints
To protect your API endpoints, use the api.auth decorator or middleware provided by Django Ninja. For example:
from ninja import Router
from ninja_jwt.authentication import JWTAuth
router = Router(auth=JWTAuth())
@router.get("/protected")
def protected_endpoint(request):
return {"message": f"Hello, {request.user.username}!"}
This ensures only requests with a valid access token can access the endpoint.
Best Practices
- Token Expiry: Configure token lifetimes in
settings.pyto balance security and usability. For example:
JWT_AUTH = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
}
- HTTPS: Always use HTTPS in production to secure token transmission.
- Refresh Token Rotation: Enable refresh token rotation to enhance security by invalidating old refresh tokens upon use.
- Error Handling: Implement proper error handling for invalid tokens or unauthorized access to provide clear feedback to clients.
Troubleshooting
- Invalid Token Errors: Ensure the token is correctly included in the
Authorizationheader asBearer <token>. - Localization Issues: Verify that
ninja_jwtis inINSTALLED_APPSand that translation files are correctly configured. - Custom Controller Errors: Double-check that your custom controller is registered with the API and that the paths are correct.
Conclusion
Integrating Django Ninja JWT into your project provides a secure and flexible way to handle API authentication. By leveraging default or custom controllers, you can tailor the authentication flow to your needs while supporting localization for a global audience. Follow the best practices outlined above to ensure a robust and secure implementation.
For more details, check the official Django Ninja JWT documentation or explore the Django Ninja and PyJWT libraries for advanced configurations.