Migration from dj-rest-auth
This guide helps you migrate from dj-rest-auth to DRF Auth Kit. Both packages provide authentication for Django REST Framework using similar underlying libraries (django-allauth, djangorestframework-simplejwt). DRF Auth Kit offers full type safety, built-in MFA support, accurate OpenAPI schema generation, and more included i18n translations.
Why Migrate?
Advantages of DRF Auth Kit over dj-rest-auth:
Full Type Safety: Complete type hints with mypy and pyright compatibility (dj-rest-auth has none)
Built-in MFA: Integrated multi-factor authentication with pluggable handlers (email, authenticator apps) - no extra setup required
Modern Django Support: Actively maintained with Django 4.2 - 6.x support
Accurate OpenAPI Schema: Full DRF Spectacular integration with accurate API documentation
Dynamic Configuration: Settings-based customization without subclassing views
More i18n Languages: Built-in translations for 57 languages
Quick Comparison
Feature |
dj-rest-auth |
DRF Auth Kit |
|---|---|---|
Type Hints |
None |
Full (mypy/pyright) |
MFA Support |
Requires separate setup |
Built-in with pluggable handlers |
Social Auth |
Auto-generated URLs |
Auto-generated URLs |
Configuration |
Class-based overrides |
Settings-based (dynamic imports) |
OpenAPI Schema |
Partial (via drf-spectacular, less accurate) |
Full (accurate schema generation) |
i18n Support |
Partial (fewer languages) |
57 languages included |
Migration Steps
Step 1: Update Dependencies
Remove dj-rest-auth and install drf-auth-kit:
# Remove old package
pip uninstall dj-rest-auth
# Install drf-auth-kit (choose one based on your needs)
pip install drf-auth-kit # Basic authentication
pip install drf-auth-kit[mfa] # With MFA support
pip install drf-auth-kit[social] # With social authentication
pip install drf-auth-kit[all] # All features
Step 2: Update INSTALLED_APPS
Before (dj-rest-auth):
INSTALLED_APPS = [
# ...
'rest_framework',
'rest_framework.authtoken', # For token auth
'dj_rest_auth',
'allauth',
'allauth.account',
'dj_rest_auth.registration', # For registration
'allauth.socialaccount', # For social auth
'allauth.socialaccount.providers.google',
]
After (DRF Auth Kit):
INSTALLED_APPS = [
# ...
'rest_framework',
'allauth',
'allauth.account',
'auth_kit', # Core authentication
# Optional: Add these based on your needs
'auth_kit.mfa', # For MFA support
'allauth.socialaccount', # For social auth
'allauth.socialaccount.providers.google',
'auth_kit.social', # For social auth integration
]
Note
rest_framework.authtoken is only needed if you use AUTH_TYPE = 'token'.
For JWT authentication (recommended), it’s not required.
Step 3: Update URL Configuration
Before (dj-rest-auth):
urlpatterns = [
path('api/auth/', include('dj_rest_auth.urls')),
path('api/auth/registration/', include('dj_rest_auth.registration.urls')),
# Social auth (if used)
path('api/auth/social/', include('allauth.socialaccount.urls')),
]
After (DRF Auth Kit):
urlpatterns = [
path('api/auth/', include('auth_kit.urls')),
# Social auth (if used) - automatically generates URLs for all providers
path('api/auth/social/', include('auth_kit.social.urls')),
]
Note
DRF Auth Kit includes registration endpoints in the main auth_kit.urls pattern.
Social URLs are automatically generated for all installed providers.
Step 4: Update Settings
Before (dj-rest-auth):
REST_AUTH = {
'USE_JWT': True,
'JWT_AUTH_COOKIE': 'jwt-auth',
'JWT_AUTH_REFRESH_COOKIE': 'jwt-refresh',
'JWT_AUTH_HTTPONLY': True,
'JWT_AUTH_SECURE': False,
'JWT_AUTH_SAMESITE': 'Lax',
'SESSION_LOGIN': False,
'OLD_PASSWORD_FIELD_ENABLED': False,
'LOGOUT_ON_PASSWORD_CHANGE': False,
'REGISTER_SERIALIZER': 'myapp.serializers.CustomRegisterSerializer',
'USER_DETAILS_SERIALIZER': 'myapp.serializers.CustomUserSerializer',
'LOGIN_SERIALIZER': 'myapp.serializers.CustomLoginSerializer',
}
After (DRF Auth Kit):
AUTH_KIT = {
# Authentication type (replaces USE_JWT)
'AUTH_TYPE': 'jwt', # 'jwt', 'token', or 'custom'
'USE_AUTH_COOKIE': True,
# Cookie settings (replaces JWT_AUTH_* settings)
'AUTH_JWT_COOKIE_NAME': 'auth-jwt',
'AUTH_JWT_REFRESH_COOKIE_NAME': 'auth-refresh-jwt',
'AUTH_COOKIE_HTTPONLY': True,
'AUTH_COOKIE_SECURE': False, # Set True in production
'AUTH_COOKIE_SAMESITE': 'Lax',
# Session and password settings
'SESSION_LOGIN': False,
'OLD_PASSWORD_FIELD_ENABLED': False,
# Custom serializers
'REGISTER_SERIALIZER': 'myapp.serializers.CustomRegisterSerializer',
'USER_SERIALIZER': 'myapp.serializers.CustomUserSerializer',
'LOGIN_REQUEST_SERIALIZER': 'myapp.serializers.CustomLoginSerializer',
}
Settings Mapping Reference:
dj-rest-auth Setting |
DRF Auth Kit Setting |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Step 5: Update Authentication Classes
Before (dj-rest-auth with JWT):
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
],
}
After (DRF Auth Kit):
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'auth_kit.authentication.JWTCookieAuthentication',
],
}
Authentication Class Mapping:
dj-rest-auth Class |
DRF Auth Kit Class |
|---|---|
|
|
|
|
Step 6: Update URL Endpoints
Most endpoints have the same paths, but some have changed:
Endpoint Mapping:
dj-rest-auth Endpoint |
DRF Auth Kit Endpoint |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
New Endpoints in DRF Auth Kit (when MFA is enabled):
POST /login/verify/- MFA code verificationPOST /login/change-method/- Change MFA method during loginPOST /login/resend/- Resend MFA codeGET|POST /mfa/- MFA method managementPOST /mfa/confirm/- Confirm MFA method setupPOST /mfa/primary/- Set primary MFA methodPOST /mfa/deactivate/- Deactivate MFA methodPOST /mfa/delete/- Delete MFA methodPOST /mfa/send/- Send MFA verification code
Step 7: Migrate Custom Serializers
If you have custom serializers, update their base classes:
Login Serializer:
# Before (dj-rest-auth)
from dj_rest_auth.serializers import LoginSerializer
class CustomLoginSerializer(LoginSerializer):
def validate(self, attrs):
# custom logic
return super().validate(attrs)
# After (DRF Auth Kit)
from auth_kit.serializers import LoginRequestSerializer
class CustomLoginSerializer(LoginRequestSerializer):
def validate(self, attrs):
# custom logic
return super().validate(attrs)
Registration Serializer:
# Before (dj-rest-auth)
from dj_rest_auth.registration.serializers import RegisterSerializer
class CustomRegisterSerializer(RegisterSerializer):
first_name = serializers.CharField(required=True)
def custom_signup(self, request, user):
user.first_name = self.validated_data.get('first_name', '')
user.save()
# After (DRF Auth Kit)
from auth_kit.serializers import RegisterSerializer
class CustomRegisterSerializer(RegisterSerializer):
first_name = serializers.CharField(required=True)
def custom_signup(self, request, user):
user.first_name = self.validated_data.get('first_name', '')
user.save()
User Serializer:
# Before (dj-rest-auth)
from dj_rest_auth.serializers import UserDetailsSerializer
class CustomUserSerializer(UserDetailsSerializer):
class Meta(UserDetailsSerializer.Meta):
fields = UserDetailsSerializer.Meta.fields + ('phone_number',)
# After (DRF Auth Kit)
from auth_kit.serializers import UserSerializer
class CustomUserSerializer(UserSerializer):
class Meta(UserSerializer.Meta):
fields = UserSerializer.Meta.fields + ('phone_number',)
Password Reset Serializer:
# Before (dj-rest-auth)
from dj_rest_auth.serializers import PasswordResetSerializer
class CustomPasswordResetSerializer(PasswordResetSerializer):
def get_email_options(self):
return {'html_email_template_name': 'email/password_reset.html'}
# After (DRF Auth Kit)
from auth_kit.serializers import PasswordResetSerializer
class CustomPasswordResetSerializer(PasswordResetSerializer):
# DRF Auth Kit uses allauth's email templates directly
# Configure templates in your allauth settings
pass
Serializer Class Mapping:
dj-rest-auth Serializer |
DRF Auth Kit Serializer |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Step 8: Migrate Custom Views
If you have custom views, update their base classes:
# Before (dj-rest-auth)
from dj_rest_auth.views import LoginView, LogoutView, UserDetailsView
class CustomLoginView(LoginView):
def post(self, request, *args, **kwargs):
# custom logic
return super().post(request, *args, **kwargs)
# After (DRF Auth Kit)
from auth_kit.views import LoginView, LogoutView, UserView
class CustomLoginView(LoginView):
def post(self, request, *args, **kwargs):
# custom logic
return super().post(request, *args, **kwargs)
Then register your custom views in settings:
AUTH_KIT = {
'LOGIN_VIEW': 'myapp.views.CustomLoginView',
'LOGOUT_VIEW': 'myapp.views.CustomLogoutView',
'USER_VIEW': 'myapp.views.CustomUserView',
}
View Class Mapping:
dj-rest-auth View |
DRF Auth Kit View |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Step 10: Run Migrations
After updating your configuration:
python manage.py migrate
Note
If you’re enabling MFA (USE_MFA = True), the migration will create the MFAMethod model.
Ensure auth_kit.mfa is in your INSTALLED_APPS before running migrations.
Response Format Changes
Login Response:
The login response format is similar but may have slight differences:
// dj-rest-auth JWT response
{
"access": "eyJ...",
"refresh": "eyJ...",
"user": {
"pk": 1,
"username": "user",
"email": "user@example.com"
}
}
// DRF Auth Kit JWT response
{
"access": "eyJ...",
"refresh": "eyJ...",
"access_expiration": "2024-01-15T12:00:00Z",
"refresh_expiration": "2024-01-22T12:00:00Z"
}
If you need user data in the login response, customize the LOGIN_RESPONSE_SERIALIZER.
With MFA enabled, first step returns:
{
"ephemeral_token": "abc123...",
"method": {
"name": "email",
"is_primary": true
}
}
Frontend Updates
If your frontend relies on specific response formats, update accordingly:
Token Storage:
Cookie names may change (
jwt-auth→auth-jwtby default)Update any JavaScript that references cookie names
Login Flow with MFA:
If you enable MFA, update your frontend to handle the two-step login:
First POST to
/api/auth/login/returnsephemeral_tokenif MFA is requiredSecond POST to
/api/auth/login/verify/withephemeral_tokenandcode
// Example frontend flow
async function login(username, password) {
const response = await fetch('/api/auth/login/', {
method: 'POST',
body: JSON.stringify({ username, password }),
});
const data = await response.json();
if (data.ephemeral_token) {
// MFA required - show MFA input
return { requiresMfa: true, ephemeralToken: data.ephemeral_token };
}
// No MFA - user is logged in
return { requiresMfa: false, tokens: data };
}
async function verifyMfa(ephemeralToken, code) {
const response = await fetch('/api/auth/login/verify/', {
method: 'POST',
body: JSON.stringify({ ephemeral_token: ephemeralToken, code }),
});
return await response.json();
}
Migration Checklist
Use this checklist to ensure a complete migration:
[ ] Remove dj-rest-auth from requirements
[ ] Install drf-auth-kit with appropriate extras
[ ] Update INSTALLED_APPS
[ ] Update URL configuration
[ ] Convert REST_AUTH settings to AUTH_KIT
[ ] Update authentication classes in REST_FRAMEWORK
[ ] Migrate custom serializers (if any)
[ ] Migrate custom views (if any)
[ ] Update social authentication setup (if used)
[ ] Run migrations
[ ] Update frontend token/cookie handling
[ ] Update frontend for MFA flow (if enabling MFA)
[ ] Test all authentication endpoints
[ ] Update API documentation references
Common Issues
Import Errors:
If you see import errors, ensure you’ve removed all dj_rest_auth imports:
# Find remaining dj_rest_auth imports
grep -r "dj_rest_auth" --include="*.py" .
Cookie Not Being Set:
Check your cookie settings:
AUTH_KIT = {
'USE_AUTH_COOKIE': True, # Must be True
'AUTH_COOKIE_SECURE': False, # Set False for HTTP (dev only)
'AUTH_COOKIE_SAMESITE': 'Lax',
}
JWT Token Issues:
Ensure SimpleJWT is configured:
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
}
Social Auth URLs Not Generated:
Ensure the provider apps are in INSTALLED_APPS and configured in SOCIALACCOUNT_PROVIDERS:
INSTALLED_APPS = [
# ...
'allauth.socialaccount.providers.google', # Provider app
'auth_kit.social', # Must come after provider apps
]
SOCIALACCOUNT_PROVIDERS = {
'google': {
'APP': {
'client_id': 'your-client-id',
'secret': 'your-secret',
}
}
}
Getting Help
Documentation: https://drf-auth-kit.readthedocs.io/
GitHub Issues: https://github.com/forthecraft/drf-auth-kit/issues
Configuration Reference: Configuration
Basic Usage Guide: Basic Usage