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

基于Django生态的微服务认证系统正确性验证及中间件优化问询

认证逻辑正确性确认与TokenAuthenticationMiddleware配置方案

一、当前认证逻辑的正确性确认

你的认证流程整体符合Django生态下的标准安全实践,细节上需注意以下几点:

  • 登录校验环节:在UserLoginSerializer中同时校验账号密码与Django Axes锁定状态是合理的——Axes的核心作用就是拦截多次登录失败请求,提前在序列化器层面校验能避免后续不必要的Token生成操作,符合安全逻辑。
  • Token生成与登录时间更新:使用Django OAuth Toolkit生成Token、调用update_last_login更新用户登录时间是标准操作,只要确保调用OTK的Token生成方法(如AccessToken.objects.create_token(user=user))正确,这部分无问题。
  • 客户端Token存储:将Token存入Session可行,但需确保后续客户端发起请求时,能以中间件可识别的方式传递Token(比如放在Authorization头的Bearer字段,或自定义Cookie),否则中间件无法完成校验。
  • 登出流程:使Token过期(可通过OTK的AccessToken.objects.revoke(token)或设置过期时间)+ 发送登出信号(如Django内置的user_logged_out)是正确的,能有效终止Token有效性并触发后续清理动作。

二、配置TokenAuthenticationMiddleware仅作用于带@login_required的视图

Django中间件默认全局执行,要实现仅对特定视图校验,可通过修改中间件的process_view方法实现,具体方案如下:

1. 中间件核心逻辑修改

在你的TokenAuthenticationMiddleware中添加视图过滤逻辑:

from django.contrib.auth.decorators import login_required
import inspect
from django.urls import resolve
from django.http import HttpResponseRedirect

class TokenAuthenticationMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # 定义需要排除的公开视图名称(根据实际视图name填写)
        self.EXEMPT_VIEWS = [
            'login',
            'password_reset',
            'password_reset_done',
            'password_reset_confirm',
            'password_reset_complete'
        ]

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def extract_token(self, request):
        # 实现从请求中提取Token的逻辑,比如从Authorization头或Cookie获取
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        if auth_header.startswith('Bearer '):
            return auth_header.split(' ')[1]
        return request.COOKIES.get('auth_token')

    def validate_token(self, token):
        # 实现Token有效性校验逻辑,调用OTK的验证方法
        from oauth2_provider.models import AccessToken
        try:
            access_token = AccessToken.objects.get(token=token)
            return not access_token.is_expired()
        except AccessToken.DoesNotExist:
            return False

    def get_user_from_token(self, token):
        # 从有效Token中获取用户
        from oauth2_provider.models import AccessToken
        return AccessToken.objects.get(token=token).user

    def process_view(self, request, view_func, view_args, view_kwargs):
        # 先判断当前视图是否在排除列表中
        resolved_url = resolve(request.path_info)
        if resolved_url.url_name in self.EXEMPT_VIEWS:
            return None  # 跳过校验

        # 判断视图是否被@login_required装饰
        view_func_actual = getattr(view_func, '_wrapped', view_func)
        has_login_required = False
        for decorator in inspect.getclosurevars(view_func_actual).nonlocals.values():
            if isinstance(decorator, login_required):
                has_login_required = True
                break

        # 仅对带@login_required的视图执行Token校验
        if has_login_required:
            token = self.extract_token(request)
            if not token or not self.validate_token(token):
                # 返回未认证响应,可根据需求调整为401或重定向
                return HttpResponseRedirect('/login/')
            # 绑定用户到request.user
            request.user = self.get_user_from_token(token)

        return None

2. 针对DRF API视图的补充处理

如果系统包含DRF API视图,通常用permission_classes = [IsAuthenticated]代替@login_required,可在process_view中补充判断:

from rest_framework.permissions import IsAuthenticated

# 在has_login_required判断后添加:
if not has_login_required:
    # 检查DRF视图的权限配置
    if hasattr(view_func, 'cls'):
        drf_view_cls = view_func.cls
        if IsAuthenticated in getattr(drf_view_cls, 'permission_classes', []):
            has_login_required = True

3. 中间件顺序配置

确保TokenAuthenticationMiddleware在django.contrib.auth.middleware.AuthenticationMiddleware之后,在settings.py的MIDDLEWARE中配置:

MIDDLEWARE = [
    # 其他中间件...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'your_app.middleware.TokenAuthenticationMiddleware',
    # 其他中间件...
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 18:20:19