Django DRF API中如何使用现有认证体系保护子应用URL路径
是否需要修改子应用配置
分两种情况:
- 若子应用的DRF视图没有显式自定义
authentication_classes、permission_classes属性,也没有使用对应的装饰器覆盖全局配置,不需要对子应用做任何修改。DRF会自动继承父应用settings.py中定义的全局认证、权限规则,新增的api/v2/路由会自动受现有OAuth2体系保护。 - 若子应用的视图单独配置了认证/权限规则,你可以选择修改子应用代码去掉自定义配置,或者使用下面的父应用层方案实现认证保护,无需改动子应用。
注意:你当前的配置只定义了默认认证类,没有配置默认权限类,DRF默认权限为
AllowAny,也就是就算校验了身份,匿名用户也能访问接口。如果需要所有接口必须登录才能访问,需要补充全局权限配置:REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ('oauth2_provider.contrib.rest_framework.OAuth2Authentication',), 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',) }
可选实现方案
1. 路由层统一配置(推荐,零子应用侵入)
不需要修改子应用代码,直接在父应用的路由文件中给api/v2/前缀的所有路由统一绑定认证和权限规则:
from rest_framework.decorators import authentication_classes, permission_classes from rest_framework.permissions import IsAuthenticated from oauth2_provider.contrib.rest_framework import OAuth2Authentication # 封装v2路由的统一认证规则 v2_routes = authentication_classes([OAuth2Authentication])( permission_classes([IsAuthenticated])( [path('', include('my_new_child_package.urls'))] ) ) urlpatterns = [ path('api/v1/', include('myapp.routes', namespace='api')), path('o/', include('oauth2_provider.urls', namespace='oauth2_provider')), # 绑定封装后的v2路由 path('api/v2/', include(v2_routes)), ]
这个方案优先级高于子应用视图的自定义配置,即使子应用内部设置了AllowAny权限,也会被路由层的配置覆盖。
2. 中间件实现(适合非DRF视图场景)
如果子应用包含普通Django视图(不是DRF视图),或者需要更灵活的路径匹配规则,可以自定义中间件统一校验api/v2/前缀的请求:
- 新增中间件文件
middleware/v2_auth.py:
from oauth2_provider.contrib.rest_framework import OAuth2Authentication from rest_framework.exceptions import AuthenticationFailed from django.http import JsonResponse class V2ApiAuthMiddleware: def __init__(self, get_response): self.get_response = get_response self.auth_validator = OAuth2Authentication() def __call__(self, request): # 只校验v2前缀的接口 if request.path.startswith('/api/v2/'): try: auth_result = self.auth_validator.authenticate(request) if not auth_result: return JsonResponse({'detail': '缺少认证凭证'}, status=401) request.user, request.auth = auth_result except AuthenticationFailed as e: return JsonResponse({'detail': str(e)}, status=401) return self.get_response(request)
- 在
settings.py的MIDDLEWARE列表中新增该中间件:
MIDDLEWARE = [ # 原有中间件 'yourapp.middleware.v2_auth.V2ApiAuthMiddleware', ]
该方案完全和子应用解耦,不需要修改子应用任何代码。
3. 子应用视图单独配置
如果只需要子应用部分接口受保护,可以直接在子应用的视图中添加认证/权限配置:
from rest_framework.viewsets import ModelViewSet from rest_framework.permissions import IsAuthenticated from oauth2_provider.contrib.rest_framework import OAuth2Authentication class YourLegacyModelViewSet(ModelViewSet): authentication_classes = [OAuth2Authentication] permission_classes = [IsAuthenticated] # 其余视图配置
内容的提问来源于stack exchange,提问作者Gonzalo
相关产品推荐
相关产品推荐

