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

使用DRF时中间件请求返回匿名用户,求替代修改源码的方案

解决方案

不用改DRF源码,有几个靠谱的办法:

1. 在自定义中间件里手动触发Token认证

DRF的TokenAuthentication本身是个可调用的类,你可以直接在中间件里调用它的认证逻辑,提前把request.user设置好。示例代码:

from rest_framework.authentication import TokenAuthentication
from rest_framework.exceptions import AuthenticationFailed
from django.http import JsonResponse

class YourCustomMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.auth = TokenAuthentication()

    def __call__(self, request):
        # 仅对DRF接口生效,避免干扰普通Django视图
        if request.path.startswith('/api/'):
            auth_header = request.META.get('HTTP_AUTHORIZATION')
            if auth_header:
                try:
                    user, token = self.auth.authenticate(request)
                    if user:
                        request.user = user
                        request.auth = token
                except AuthenticationFailed:
                    # 按业务需求处理认证失败,比如直接返回401
                    return JsonResponse({'detail': 'Invalid token'}, status=401)

        response = self.get_response(request)
        return response

注意要限定作用路径,避免影响非API视图;认证失败的处理可以根据实际需求调整,比如不需要直接拦截就跳过,继续走后续流程。

2. 把中间件逻辑迁移到DRF的权限类

如果你的拦截逻辑是针对接口权限的,完全可以把逻辑放到DRF的自定义权限类里——DRF的认证流程会先于权限检查执行,此时request.user已经是认证后的用户。

示例自定义权限类:

from rest_framework.permissions import BasePermission

class YourCustomPermission(BasePermission):
    def has_permission(self, request, view):
        # 这里已能拿到认证后的request.user
        if not request.user.is_authenticated:
            return False
        # 你的自定义拦截逻辑,比如检查用户角色、权限标识等
        return request.user.has_perm('your_app.some_permission')

然后全局配置到DRF设置中,让所有接口自动生效:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'your_app.permissions.YourCustomPermission',
    ]
}

这种方式更贴合DRF的生态,比中间件更适合接口权限场景。

3. 用DRF基类视图统一处理

如果不想全局生效,可以写一个基类视图,把拦截逻辑放到dispatch方法里,让需要检查的业务视图继承这个基类:

from rest_framework.views import APIView
from rest_framework.response import Response

class BaseAuthenticatedAPIView(APIView):
    authentication_classes = [TokenAuthentication]

    def dispatch(self, request, *args, **kwargs):
        # 先执行父类dispatch完成认证
        response = super().dispatch(request, *args, **kwargs)
        # 在这里添加自定义拦截逻辑,比如请求处理前/后的检查
        if not request.user.is_authenticated:
            return Response({'detail': 'Unauthorized'}, status=401)
        # 其他业务检查逻辑
        return response

后续业务视图只需继承这个基类,就能自动带上认证和拦截逻辑。

内容的提问来源于stack exchange,提问作者Oasis Inc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:05:09