找回密码
 立即注册
首页 业界区 业界 DRF 认证

DRF 认证

战匈琼 昨天 15:58
Django REST Framework 提供了强大且灵活的认证系统,允许您轻松地保护 API 端点。
认证流程
请求到达 → 认证检查 → 权限检查 → 限流检查 → 视图处理
1、BaseAuthentication

认证基类
  1. class BaseAuthentication:
  2.     """
  3.     所有身份验证类都应该扩展BaseAuthentication。
  4.     """
  5.     def authenticate(self, request):
  6.         """
  7.         子类必须覆盖该方法, 认证成功后,request.user 和 request.auth 属性会被设置,如果认证失败,可能抛出异常或返回 None
  8.         """
  9.         raise NotImplementedError(".authenticate() must be overridden.")
  10.     def authenticate_header(self, request):
  11.         """
  12.         """
  13.         pass
复制代码
2、JSON Web Token (JWT) 认证

基于 JWT 的认证,适合现代无状态 API。
安装
  1. pip install djangorestframework-simplejwt
复制代码
全局配置
  1. # settings.py
  2. REST_FRAMEWORK = {
  3.     'DEFAULT_AUTHENTICATION_CLASSES': [
  4.         'rest_framework_simplejwt.authentication.JWTAuthentication',
  5.     ],
  6. }
  7. SIMPLE_JWT = {
  8.     'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
  9.     'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
  10.     'ROTATE_REFRESH_TOKENS': False,
  11.     'BLACKLIST_AFTER_ROTATION': True,
  12. }
复制代码
URL 配置
  1. # urls.py
  2. from rest_framework_simplejwt.views import (
  3.     TokenObtainPairView,
  4.     TokenRefreshView,
  5.     TokenVerifyView,
  6. )
  7. urlpatterns = [
  8.     path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
  9.     path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
  10.     path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
  11. ]
复制代码
源码
  1. class JWTAuthentication(authentication.BaseAuthentication):
  2.     def authenticate(self, request: Request) -> Optional[tuple[AuthUser, Token]]:
  3.         """
  4.         从请求头提取 Token → 验证 Token → 获取用户
  5.         """
  6.     def authenticate_header(self, request: Request) -> str:
  7.         return '{} realm="{}"'.format(
  8.             AUTH_HEADER_TYPES[0],
  9.             self.www_authenticate_realm,
  10.         )
  11.     def get_header(self, request: Request) -> bytes:
  12.         """       
  13.         从 Authorization请求头获取 JWT 字符串, 默认查找 Authorization: Bearer <token>
  14.         """
  15.     def get_raw_token(self, header: bytes) -> Optional[bytes]:
  16.         """
  17.         从头部字符串中提取纯粹的 Token 内容
  18.         """
  19.         
  20.     def get_validated_token(self, raw_token: bytes) -> Token:
  21.         """
  22.         验证 Token 签名、检查过期时间、确认结构完整性, 依赖 api_settings.JWT_PAYLOADVALIDATOR, 无效时抛出 InvalidToken异常
  23.         """
  24.         
  25.     def get_user(self, validated_token: Token) -> AuthUser:
  26.         """
  27.         从验证后的 Token 载荷 (Payload) 中提取用户标识 (如 user_id),并查询数据库获取用户对象, 依赖 api_settings.USER_ID_FIELD, 用户不存在时抛出 AuthenticationFailed异常
  28.         """
复制代码
3、使用

settings.py

配置会将 JWTAuthentication应用于所有 DRF 视图
局部启用/禁用,优先级高于全局配置

视图级认证配置
  1. # 局部启用
  2. from rest_framework_simplejwt.authentication import JWTAuthentication
  3. from rest_framework.views import APIView
  4. class ExampleView(APIView):
  5.     authentication_classes = [JWTAuthentication]
  6.     # ...
  7. # 局部禁用(设为空列表)
  8. class PublicView(APIView):
  9.     authentication_classes = []
  10.     # ...
复制代码
基于函数的视图配置
使用 @api_view 装饰器
  1. from rest_framework.decorators import api_view, authentication_classes,
  2. @api_view(['GET'])
  3. @authentication_classes([TokenAuthentication])
  4. def example_view(request):
  5.     return Response({"message": "Authenticated successfully"})
复制代码
4. 自定义认证类

创建自定义认证类需要继承 BaseAuthentication 并实现 authenticate 方法
  1. # authentication.py
  2. from rest_framework.authentication import BaseAuthentication
  3. from rest_framework.exceptions import AuthenticationFailed
  4. from django.contrib.auth.models import User
  5. from django.conf import settings
  6. class APIKeyAuthentication(BaseAuthentication):
  7.     """
  8.     自定义API密钥认证
  9.     """
  10.    
  11.     def authenticate(self, request):
  12.         # 从请求头获取API密钥
  13.         api_key = request.META.get('HTTP_X_API_KEY')
  14.         
  15.         if not api_key:
  16.             return None  # 没有提供认证信息
  17.         
  18.         # 验证API密钥
  19.         if api_key != settings.API_KEY:
  20.             raise AuthenticationFailed('Invalid API key')
  21.         
  22.         # 返回用户对象和认证凭证
  23.         # 这里可以返回一个特定用户或匿名用户
  24.         user, created = User.objects.get_or_create(
  25.             username='api_client',
  26.             defaults={'is_active': True}
  27.         )
  28.         
  29.         return (user, {'api_key': api_key})
  30.    
  31.     def authenticate_header(self, request):
  32.         """
  33.         返回WWW-Authenticate头的值
  34.         """
  35.         return 'APIKey'
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册