django-rest-knox: DRF Token Authentication
django-rest-knox provides robust token-based authentication for Django REST Framework. It supports multiple tokens per user, token expiration, and single-token or all-token logout functionality. Maintained by Jazzband, the library is actively developed, with its current version being 5.0.4.
Warnings
- breaking Tokens created prior to django-rest-knox 5.0.0 are no longer valid due to internal changes in token generation and storage.
- breaking The `create()` method on the `AuthToken` model changed its signature and return value in 4.0.0. It now returns `(instance, token)` instead of just `token`. Additionally, the `AuthToken` model field `expires` was renamed to `expiry`.
- breaking The `salt` field of the `AuthToken` model was removed in version 4.2.0. This change requires a migration.
- gotcha Potential N+1 query issue fixed in 5.0.4 on `AuthToken.user` access. Older versions might suffer performance degradation in scenarios retrieving tokens and accessing their associated users.
- gotcha If `AUTO_REFRESH = True`, tokens could theoretically live forever. Version 5.0.2 introduced `AUTO_REFRESH_MAX_TTL` to limit the total lifetime of such tokens.
- gotcha A migration issue existed in 5.0.1 when not overriding the `AuthToken` model, which could prevent migrations from running correctly.
Install
-
pip install django-rest-knox
Imports
- TokenAuthentication
from knox.auth import TokenAuthentication
- AuthToken
from knox.models import AuthToken
- LoginView
from knox.views import LoginView
- LogoutView
from knox.views import LogoutView
- LogoutAllView
from knox.views import LogoutAllView
Quickstart
import os
import django
from django.conf import settings
from django.urls import path, include
from django.http import JsonResponse
# Minimal Django settings for quickstart
if not settings.configured:
settings.configure(
DEBUG=True,
INSTALLED_APPS=[
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'rest_framework',
'knox',
],
SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-dev'),
ROOT_URLCONF=__name__,
DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
REST_FRAMEWORK={
'DEFAULT_AUTHENTICATION_CLASSES': [
'knox.auth.TokenAuthentication',
]
},
)
django.setup()
from rest_framework import permissions
from rest_framework.authtoken.views import obtain_auth_token
from knox.views import LoginView as KnoxLoginView, LogoutView, LogoutAllView
from django.contrib.auth.models import User # For example purposes
# Create a dummy user for testing
if not User.objects.filter(username='testuser').exists():
User.objects.create_user(username='testuser', email='test@example.com', password='password123')
def hello_view(request):
return JsonResponse({'message': 'Hello, API!', 'user': str(request.user), 'authenticated': request.user.is_authenticated})
urlpatterns = [
# Knox authentication URLs
path('api/auth/login/', KnoxLoginView.as_view(), name='knox_login'),
path('api/auth/logout/', LogoutView.as_view(), name='knox_logout'),
path('api/auth/logoutall/', LogoutAllView.as_view(), name='knox_logoutall'),
# Protected example view
path('api/hello/', hello_view, name='hello'),
]
# To run:
# 1. Save as a .py file (e.g., quickstart.py)
# 2. python manage.py makemigrations knox (if you create a new project structure)
# 3. python manage.py migrate
# 4. Create a superuser: python manage.py createsuperuser (or use the dummy user created above)
# 5. python manage.py runserver
#
# Test with curl:
# Login (creates token):
# curl -X POST -H "Content-Type: application/json" -d '{"username":"testuser", "password":"password123"}' http://127.0.0.1:8000/api/auth/login/
#
# Access protected endpoint with token (replace YOUR_TOKEN_VALUE):
# curl -H "Authorization: Token YOUR_TOKEN_VALUE" http://127.0.0.1:8000/api/hello/
#
# Logout:
# curl -X POST -H "Authorization: Token YOUR_TOKEN_VALUE" http://127.0.0.1:8000/api/auth/logout/