{"id":9679,"library":"django-ninja-jwt","title":"Django Ninja JWT","description":"Django Ninja JWT provides JSON Web Token (JWT) authentication for Django Ninja, a fast API framework for Django. It handles token creation, refresh, and authentication seamlessly within Django Ninja API routes, building upon `djangorestframework-simplejwt`. The current version is 5.4.4, with a regular release cadence focused on bug fixes and compatibility updates.","status":"active","version":"5.4.4","language":"en","source_language":"en","source_url":"https://github.com/eadwinCode/django-ninja-jwt","tags":["django","django-ninja","jwt","authentication","api"],"install":[{"cmd":"pip install django-ninja-jwt","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core Django framework requirement.","package":"django","optional":false},{"reason":"The API framework this library extends.","package":"django-ninja","optional":false},{"reason":"Used for JWT encoding and decoding operations.","package":"python-jose","optional":false},{"reason":"Provides the underlying JWT functionality and configuration patterns.","package":"djangorestframework-simplejwt","optional":false}],"imports":[{"symbol":"JWTAuth","correct":"from ninja_jwt.authentication import JWTAuth"},{"symbol":"AuthRouter","correct":"from ninja_jwt.views import AuthRouter"},{"note":"While django-ninja-jwt uses simplejwt, it re-exports tokens under its own namespace for consistency.","wrong":"from rest_framework_simplejwt.tokens import AccessToken","symbol":"AccessToken","correct":"from ninja_jwt.tokens import AccessToken"}],"quickstart":{"code":"import os\nfrom datetime import timedelta\n\n# --- In your Django project's settings.py ---\n\nSECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'your-very-secret-key-for-development') # IMPORTANT: Use a strong key in production\n\nINSTALLED_APPS = [\n    # ... other apps\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"ninja\", # Add django-ninja\n    \"ninja_jwt\", # Add this\n    # ...\n]\n\n# Configure JWT settings (mimics djangorestframework-simplejwt settings)\nSIMPLE_JWT = {\n    \"ACCESS_TOKEN_LIFETIME\": timedelta(minutes=5), # Short lifetime for access tokens\n    \"REFRESH_TOKEN_LIFETIME\": timedelta(days=1),  # Longer lifetime for refresh tokens\n    \"ROTATE_REFRESH_TOKENS\": False,\n    \"BLACKLIST_AFTER_ROTATION\": False,\n    \"UPDATE_LAST_LOGIN\": False,\n    \"ALGORITHM\": \"HS256\",\n    \"SIGNING_KEY\": SECRET_KEY, # Crucial: use a strong, unique secret key here!\n    \"VERIFYING_KEY\": None,\n    \"AUDIENCE\": None,\n    \"ISSUER\": None,\n    \"AUTH_HEADER_TYPES\": (\"Bearer\",),\n    \"AUTH_TOKEN_CLASSES\": (\"ninja_jwt.tokens.AccessToken\",),\n    \"TOKEN_TYPE_CLAIM\": \"token_type\",\n    \"JTI_CLAIM\": \"jti\",\n}\n\nAUTHENTICATION_BACKENDS = [\n    'django.contrib.auth.backends.ModelBackend', # For default Django user auth\n    'ninja_jwt.authentication.JWTAuthBackend',   # Important for token authentication\n]\n\n# --- In your_project/urls.py (main project urls) ---\n\nfrom django.contrib import admin\nfrom django.urls import path\nfrom ninja import NinjaAPI\nfrom ninja_jwt.views import AuthRouter\nfrom ninja_jwt.authentication import JWTAuth\n\n# Create your NinjaAPI instance\napi = NinjaAPI(\n    version=\"1.0.0\",\n    title=\"My Django Ninja JWT API\"\n)\n\n# Add the JWT authentication routes (e.g., /api/auth/token, /api/auth/token/refresh)\napi.add_router(\"auth/\", AuthRouter())\n\n# Example protected endpoint\n@api.get(\"/hello\", auth=JWTAuth()) # Use JWTAuth to protect this endpoint\ndef protected_hello(request):\n    return {\"message\": f\"Hello, {request.user.username}! You are authenticated.\"}\n\nurlpatterns = [\n    path('admin/', admin.site.urls),\n    path(\"api/\", api.urls), # Mount your Ninja API\n]\n\n# To run this example:\n# 1. Ensure Django and django-ninja-jwt are installed.\n# 2. Add 'ninja' and 'ninja_jwt' to INSTALLED_APPS in settings.py.\n# 3. Configure SIMPLE_JWT and AUTHENTICATION_BACKENDS as shown.\n# 4. Run `python manage.py makemigrations` and `python manage.py migrate`.\n# 5. Create a superuser: `python manage.py createsuperuser`.\n# 6. Run the development server: `python manage.py runserver`.\n# 7. Test:\n#    - POST to /api/auth/token/ with {\"username\": \"youruser\", \"password\": \"yourpassword\"} to get tokens.\n#    - GET to /api/hello/ with 'Authorization: Bearer <your_access_token>' header.","lang":"python","description":"This quickstart demonstrates how to set up `django-ninja-jwt` in a Django project. It covers adding the library to `INSTALLED_APPS`, configuring `SIMPLE_JWT` settings, specifying `AUTHENTICATION_BACKENDS`, and integrating the `AuthRouter` for token management endpoints. It also shows how to protect an API endpoint using `JWTAuth()`."},"warnings":[{"fix":"Ensure Pydantic is updated to a compatible version (v2.0+) if using custom settings schemas. Review your `SIMPLE_JWT` configuration for any deprecated `Config` attributes, as older versions might have used them.","message":"Django Ninja JWT migrated its internal settings handling to Pydantic v2 in version `5.4.2`. If your project uses custom settings classes or older Pydantic versions that conflict, you may encounter validation errors related to the settings schema.","severity":"breaking","affected_versions":"5.4.2+"},{"fix":"In `settings.py`, ensure `SIMPLE_JWT[\"SIGNING_KEY\"] = settings.SECRET_KEY` (or a dedicated `JWT_SIGNING_KEY` environment variable) is configured with a robust, randomly generated key. Never hardcode sensitive keys in production.","message":"For security and proper token signing, the `SIGNING_KEY` within the `SIMPLE_JWT` settings must be set to a strong, unique secret key. By default, it often falls back to `settings.SECRET_KEY`, but explicitly setting it (or ensuring `SECRET_KEY` is robust) is critical. Leaving it unset or weak leads to severe security vulnerabilities.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Add `'ninja_jwt.authentication.JWTAuthBackend'` to your `AUTHENTICATION_BACKENDS` list in `settings.py`. Ensure `django.contrib.auth.backends.ModelBackend` is also present if you use Django's default user authentication methods.","message":"If `django-ninja-jwt` fails to authenticate users even with correct tokens, a common cause is missing `ninja_jwt.authentication.JWTAuthBackend` from your `AUTHENTICATION_BACKENDS` list in `settings.py`. Django's default `ModelBackend` handles username/password, but the JWT backend is essential for token verification.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Set `SIMPLE_JWT[\"SIGNING_KEY\"]` to a strong secret key, typically `settings.SECRET_KEY` or an environment variable, in your `settings.py`.","cause":"The `SIMPLE_JWT['SIGNING_KEY']` setting is either not defined or explicitly set to an empty string in `settings.py`.","error":"django.core.exceptions.ImproperlyConfigured: The 'SIGNING_KEY' setting must not be empty."},{"fix":"Verify the `Authorization: Bearer <token>` header format. Check token expiration. Ensure `AUTHENTICATION_BACKENDS` in `settings.py` includes `'ninja_jwt.authentication.JWTAuthBackend'`.","cause":"The `Authorization` header is malformed, the token type is incorrect (e.g., missing \"Bearer \"), the token is expired, or the `AUTHENTICATION_BACKENDS` is not properly configured.","error":"AuthenticationFailed: Authentication credentials were not provided. (or 'Given token not valid for any token type')"},{"fix":"Ensure `auth=JWTAuth()` is correctly applied to your `DjangoNinja` API endpoint. Verify that `AUTHENTICATION_BACKENDS` in `settings.py` includes `'ninja_jwt.authentication.JWTAuthBackend'`.","cause":"The user object is not being attached to the request, usually because `JWTAuth()` is not correctly applied to the API endpoint or the `AUTHENTICATION_BACKENDS` configuration is incomplete.","error":"AttributeError: 'WSGIRequest' object has no attribute 'user' (within a protected endpoint)"},{"fix":"Run `pip install django-ninja-jwt`. Verify that `'ninja_jwt'` is in your `INSTALLED_APPS` list in `settings.py`. Double-check import statements: `from ninja_jwt.views import AuthRouter` and `from ninja_jwt.authentication import JWTAuth`.","cause":"The `django-ninja-jwt` library is not installed, or `ninja_jwt` is missing from `INSTALLED_APPS`, or the import path for a symbol is incorrect.","error":"ModuleNotFoundError: No module named 'ninja_jwt' OR ImportError: cannot import name 'AuthRouter' from 'ninja_jwt.views'"}]}