Django REST Framework 提供了强大且灵活的认证系统,允许您轻松地保护 API 端点。
认证流程
请求到达 → 认证检查 → 权限检查 → 限流检查 → 视图处理
1、BaseAuthentication
认证基类
python
class BaseAuthentication:
"""
所有身份验证类都应该扩展BaseAuthentication。
"""
def authenticate(self, request):
"""
子类必须覆盖该方法, 认证成功后,request.user 和 request.auth 属性会被设置,如果认证失败,可能抛出异常或返回 None
"""
raise NotImplementedError(".authenticate() must be overridden.")
def authenticate_header(self, request):
"""
"""
pass
2、JSON Web Token (JWT) 认证
基于 JWT 的认证,适合现代无状态 API。
安装
bash
pip install djangorestframework-simplejwt
全局配置
python
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
}
URL 配置
python
# urls.py
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView,
)
urlpatterns = [
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
]
源码
python
class JWTAuthentication(authentication.BaseAuthentication):
def authenticate(self, request: Request) -> Optional[tuple[AuthUser, Token]]:
"""
从请求头提取 Token → 验证 Token → 获取用户
"""
def authenticate_header(self, request: Request) -> str:
return '{} realm="{}"'.format(
AUTH_HEADER_TYPES[0],
self.www_authenticate_realm,
)
def get_header(self, request: Request) -> bytes:
"""
从 Authorization请求头获取 JWT 字符串, 默认查找 Authorization: Bearer <token>
"""
def get_raw_token(self, header: bytes) -> Optional[bytes]:
"""
从头部字符串中提取纯粹的 Token 内容
"""
def get_validated_token(self, raw_token: bytes) -> Token:
"""
验证 Token 签名、检查过期时间、确认结构完整性, 依赖 api_settings.JWT_PAYLOADVALIDATOR, 无效时抛出 InvalidToken异常
"""
def get_user(self, validated_token: Token) -> AuthUser:
"""
从验证后的 Token 载荷 (Payload) 中提取用户标识 (如 user_id),并查询数据库获取用户对象, 依赖 api_settings.USER_ID_FIELD, 用户不存在时抛出 AuthenticationFailed异常
"""
3、使用
settings.py
配置会将 JWTAuthentication应用于所有 DRF 视图
局部启用/禁用,优先级高于全局配置
视图级认证配置
python
# 局部启用
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.views import APIView
class ExampleView(APIView):
authentication_classes = [JWTAuthentication]
# ...
# 局部禁用(设为空列表)
class PublicView(APIView):
authentication_classes = []
# ...
基于函数的视图配置
使用 @api_view 装饰器
python
from rest_framework.decorators import api_view, authentication_classes,
@api_view(['GET'])
@authentication_classes([TokenAuthentication])
def example_view(request):
return Response({"message": "Authenticated successfully"})
4. 自定义认证类
创建自定义认证类需要继承 BaseAuthentication 并实现 authenticate 方法
python
# authentication.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from django.contrib.auth.models import User
from django.conf import settings
class APIKeyAuthentication(BaseAuthentication):
"""
自定义API密钥认证
"""
def authenticate(self, request):
# 从请求头获取API密钥
api_key = request.META.get('HTTP_X_API_KEY')
if not api_key:
return None # 没有提供认证信息
# 验证API密钥
if api_key != settings.API_KEY:
raise AuthenticationFailed('Invalid API key')
# 返回用户对象和认证凭证
# 这里可以返回一个特定用户或匿名用户
user, created = User.objects.get_or_create(
username='api_client',
defaults={'is_active': True}
)
return (user, {'api_key': api_key})
def authenticate_header(self, request):
"""
返回WWW-Authenticate头的值
"""
return 'APIKey'