You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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/前缀的请求:

  1. 新增中间件文件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)
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 02:39:01