Django REST Framework JWT 认证实战指南 ——基于 djangorestframework-simplejwt 的完整解决方案
本文介绍了Django REST框架中使用Simple JWT实现认证的完整方案。
·
一、环境搭建与配置
1. 安装依赖库
pip install djangorestframework-simplejwt==5.2.2
2. 基础配置
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework_simplejwt',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
# JWT 高级配置
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': True
}
二、核心功能实现
1. 路由配置
# urls.py
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
...
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
2. 自定义用户模型
# models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
phone = models.CharField(max_length=20, unique=True)
avatar = models.URLField(blank=True)
三、进阶功能开发
1. 自定义 Token 负载
# serializers.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CustomTokenSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
# 添加自定义声明
token['name'] = user.username
token['avatar'] = user.avatar
return token
# views.py
class CustomTokenView(TokenObtainPairView):
serializer_class = CustomTokenSerializer
2. Token 黑名单机制
# apps.py (新建jwt_blacklist应用)
from django.db import models
class BlacklistedToken(models.Model):
token = models.CharField(max_length=255, unique=True)
blacklisted_at = models.DateTimeField(auto_now_add=True)
# authentication.py
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken
from .models import BlacklistedToken
class CustomJWTAuthentication(JWTAuthentication):
def authenticate(self, request):
raw_token = self.get_raw_token(request)
if BlacklistedToken.objects.filter(token=raw_token).exists():
raise InvalidToken('Token已被注销')
return super().authenticate(request)
四、安全增强方案
1. 强制 HTTPS 传输
# settings.py
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
2. 防御重放攻击
# middleware.py
import time
from django.utils.deprecation import MiddlewareMixin
class ReplayAttackMiddleware(MiddlewareMixin):
def process_request(self, request):
timestamp = request.META.get('HTTP_X_TIMESTAMP')
if timestamp and abs(time.time() - float(timestamp)) > 300:
return HttpResponse('请求已过期', status=400)
五、前端集成示例
1. 登录获取 Token
// 使用 axios
axios.post('/api/token/', {
username: 'admin',
password: 'admin123'
}).then(response => {
localStorage.setItem('access', response.data.access)
localStorage.setItem('refresh', response.data.refresh)
})
2. 自动刷新 Token
// 请求拦截器
axios.interceptors.response.use(
response => response,
error => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
return axios.post('/api/token/refresh/', {
refresh: localStorage.getItem('refresh')
}).then(res => {
localStorage.setItem('access', res.data.access)
return axios(originalRequest);
})
}
return Promise.reject(error);
}
);
六、测试方案设计
1. 单元测试模板
from rest_framework.test import APITestCase
class AuthTests(APITestCase):
def test_jwt_login(self):
user = User.objects.create_user(username='test', password='test123')
response = self.client.post('/api/token/', {
'username': 'test',
'password': 'test123'
})
self.assertEqual(response.status_code, 200)
self.assertIn('access', response.data)
2. Postman 测试集
{
"info": {
"name": "JWT Auth Flow",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "获取Token",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\"username\": \"admin\", \"password\": \"admin123\"}"
},
"url": "{{base_url}}/api/token/"
}
}
]
}
七、部署注意事项
1. 密钥管理规范
# 生成安全密钥
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
# 环境变量配置
export SECRET_KEY='your_generated_key'
export SIMPLE_JWT={'SIGNING_KEY': '$SECRET_KEY'}
2. 性能监控指标
| 指标 | 预警阈值 | 监控工具 |
|---|---|---|
| Token生成耗时 | > 500ms | New Relic |
| 认证失败率 | > 5% | Datadog |
| 刷新Token使用率 | < 10% | Prometheus + Grafana |
通过本教程,您已完成从基础配置到高级安全策略的完整 JWT 认证体系搭建。建议结合 OWASP JWT 最佳实践 进行深度安全加固。
更多推荐
所有评论(0)