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

Django REST API如何实现全局登录校验避免每个接口重复代码

方案1:自定义DRF全局/局部认证类(最推荐,符合DRF设计规范)

DRF本身就支持自定义认证类,会在请求进入视图函数前自动执行校验逻辑,校验失败直接返回错误,完全不用在每个视图里写判断。

首先编写自定义认证类:

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

class JWTLoginAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 将原有verify_login逻辑挪到此处
        verify_response = verify_login(request)
        if verify_response is not None:
            # 抛出认证失败异常,DRF会自动转换为对应HTTP响应
            raise AuthenticationFailed(detail=verify_response.data, code=verify_response.status_code)
        # 校验成功返回(用户对象, None),后续视图可直接通过request.user获取用户信息
        return (request.user, None)

使用方式分两种:

  • 全局生效:在settings.py中配置REST_FRAMEWORK的默认认证类,所有接口默认走校验逻辑,无需单独配置视图
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        '你的模块路径.JWTLoginAuthentication',
    ]
}
  • 局部生效:仅给需要校验的视图添加,公开接口(比如登录、注册)无需配置,直接在视图类指定认证类属性即可
class PostView(APIView):
    authentication_classes = [JWTLoginAuthentication]
    # 后续post、get方法完全不需要编写校验代码,进入方法的请求均已校验通过
    @swagger_auto_schema(
        request_body=PostSerializer,
        operation_description="Create a post object"
    )
    def post(self, request):
        serializer = PostSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    @swagger_auto_schema(
        operation_description="Get all posts from the DB"
    )
    def get(self, request):
        posts = Post.objects.all()
        serializer = PostSerializer(posts, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)
方案2:自定义装饰器(适合函数视图、仅部分方法需要校验的场景)

如果只有个别接口的个别方法需要登录校验,不想改动全局配置或整个视图的认证逻辑,可以用装饰器实现:

from functools import wraps

def login_required(func):
    @wraps(func)
    def wrapper(view_instance, request, *args, **kwargs):
        verify_response = verify_login(request)
        if verify_response is not None:
            return verify_response
        return func(view_instance, request, *args, **kwargs)
    return wrapper

使用时直接给需要校验的方法加装饰器即可:

class PostView(APIView):
    @swagger_auto_schema(
        request_body=PostSerializer,
        operation_description="Create a post object"
    )
    @login_required
    def post(self, request):
        # 无需额外编写校验逻辑
        serializer = PostSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
方案3:重写父类APIView的dispatch方法

你之前考虑的继承父类方案也可以实现,只要重写请求分发的入口方法dispatch即可,不需要每个方法单独调用父类逻辑:

class BaseAuthAPIView(APIView):
    def dispatch(self, request, *args, **kwargs):
        # dispatch是所有请求进入视图方法的统一入口,在此处提前做校验
        verify_response = verify_login(request)
        if verify_response is not None:
            return verify_response
        # 校验通过后再执行原生请求分发逻辑,进入对应get/post方法
        return super().dispatch(request, *args, **kwargs)

使用时所有需要登录校验的视图直接继承BaseAuthAPIView即可,无需编写任何校验代码:

class PostView(BaseAuthAPIView):
    # 后续业务方法无需额外处理校验
    def post(self, request):
        # 业务逻辑
        ...

以上三种方案均符合DRY原则,无需重复编写校验代码,优先推荐方案1,是DRF原生支持的标准用法,适配性最高,也方便后续扩展权限校验等能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 23:33:00