Upgraded the authentication system from permanent tokens to JWT (JSON Web Tokens) with expiration for improved security.
-
Added JWT Package (requirements.txt)
- Added
djangorestframework-simplejwt>=5.3.0
- Added
-
Updated Settings (base.py)
- Added
rest_framework_simplejwtandrest_framework_simplejwt.token_blacklistto INSTALLED_APPS - Configured JWT settings with 1-hour access tokens and 7-day refresh tokens
- Enabled token rotation and blacklisting
- Added
-
Updated Authentication Views (authentication/views.py)
login_view: Now returnsaccessandrefreshJWT tokens instead of permanent tokenlogout_view: Blacklists refresh token instead of deleting from databaseregister_view: Returns JWT tokens on registration
-
Added Token Refresh Endpoint (authentication/urls.py)
POST /api/auth/token/refresh/- Get new access token using refresh token
-
Updated Login Component (Login.svelte)
- Stores
accessTokenandrefreshTokeninstead ofauthToken
- Stores
-
Updated Logoff Page (logoff/+page.svelte)
- Uses
Bearertoken instead ofToken - Sends refresh token to backend for blacklisting
- Clears both access and refresh tokens from localStorage
- Uses
-
Created Auth Utility (lib/utils/auth.js)
refreshAccessToken()- Automatically refresh expired access tokensauthenticatedFetch()- Make authenticated requests with auto-refreshisAuthenticated()- Check if user is logged ingetCurrentUser()- Get current user from localStorage
| Feature | Old System | New System |
|---|---|---|
| Token Expiration | ❌ Never expires | ✅ 1 hour (access), 7 days (refresh) |
| Token Type | Permanent DB token | JWT with claims |
| Token Refresh | ❌ Not supported | ✅ Automatic refresh |
| Token Revocation | Delete from DB | ✅ Blacklist on logout |
| Stolen Token Risk | ✅ Limited to 1 hour | |
| Auto Logout | ❌ Manual only | ✅ On token expiry |
cd pilot-backend
pip install djangorestframework-simplejwt>=5.3.0Or using the requirements file:
pip install -r requirements.txtpython manage.py migrateThis will create the token blacklist tables:
token_blacklist_outstandingtokentoken_blacklist_blacklistedtoken
curl -X POST http://localhost:8000/api/auth/login/ \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "password": "password123"}'Expected response:
{
"success": true,
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"id": 1,
"username": "testuser",
"email": "test@example.com"
}
}curl -X POST http://localhost:8000/api/auth/token/refresh/ \
-H "Content-Type: application/json" \
-d '{"refresh": "YOUR_REFRESH_TOKEN"}'curl -X GET http://localhost:8000/api/auth/user/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Login/Register
↓
Receive access (1h) + refresh (7d) tokens
↓
Store in localStorage
↓
Make API requests with access token
↓
Access token expires after 1 hour
↓
Frontend detects 401 response
↓
Automatically refresh using refresh token
↓
Retry request with new access token
↓
If refresh token expired (7 days)
↓
Redirect to login page
Existing users will need to re-login after this upgrade because:
- Old permanent tokens are incompatible with JWT
- The authentication header format changed from
TokentoBearer - Frontend now expects
accessandrefreshtokens
The old authtoken_token table is no longer used but can remain for backward compatibility or be removed:
# Optional: Remove old token auth app from INSTALLED_APPS
# Then run:
python manage.py migrate authtoken zeroToken lifetimes can be adjusted in base.py:
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(hours=1), # Adjust access token lifetime
'REFRESH_TOKEN_LIFETIME': timedelta(days=7), # Adjust refresh token lifetime
'ROTATE_REFRESH_TOKENS': True, # Generate new refresh on refresh
'BLACKLIST_AFTER_ROTATION': True, # Blacklist old refresh tokens
}Solution: User tried to use an old refresh token. They need to login again.
Solution: Frontend should automatically refresh. Check that auth.js utility is being used.
Solution: Verify Authorization header format is Bearer <token> not Token <token>
Solution: Refresh token has expired (7 days). User must login again.
- Add HTTP-only cookies - Store refresh tokens in HTTP-only cookies instead of localStorage
- Implement refresh token rotation - Already enabled, but monitor blacklist table growth
- Add rate limiting - Prevent brute force attacks on login endpoint
- Add 2FA - Two-factor authentication for additional security
- Monitor token usage - Track token refresh patterns for suspicious activity
For questions or issues, please check:
- README.md - General authentication documentation
- Django REST Framework SimpleJWT docs