Django如何结合身份认证中间件与自定义中间件实现权限校验
问题解答
问题1:将IsAuthenticated校验逻辑迁移到中间件简化代码的实现方案
IsAuthenticated的核心校验逻辑就是确认请求携带有效身份凭证、对应用户处于活跃状态,你可以直接把这部分逻辑整合到现有中间件里,替换所有视图的permission_classes配置,完整实现如下:
from django.http import HttpResponseForbidden from rest_framework.authtoken.models import Token class CustomMiddleware(object): def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 放行不需要认证的公开接口,比如登录、注册、健康检查接口 open_paths = ["/api/login/", "/api/register/"] if request.path in open_paths: return self.get_response(request) # 校验认证头是否合法 auth_header = request.headers.get("Authorization") if not auth_header or not auth_header.startswith("Token "): return HttpResponseForbidden("缺少合法认证信息") # 校验token有效性 try: token = auth_header.split(" ")[1] token_obj = Token.objects.get(key=token) user = token_obj.user except Token.DoesNotExist: return HttpResponseForbidden("无效Token") # 对应IsAuthenticated的核心校验:用户是否活跃 if not user.is_active: return HttpResponseForbidden("用户已被禁用") # 校验is_staff权限 if not user.is_staff: return HttpResponseForbidden("无访问权限") # 把解析好的用户绑定到request对象,视图中可直接调用request.user request.user = user return self.get_response(request)
记得将该中间件注册到settings.py的MIDDLEWARE列表中,位置放在CommonMiddleware之后即可,之后所有视图都可以删除permission_classes = (IsAuthenticated, )配置。
问题2:解决AttributeError: 'WSGIRequest' object has no attribute 'auth'报错
request.auth是DRF框架的认证模块执行完成后才会注入到请求对象的属性,而自定义中间件的执行顺序早于DRF的认证逻辑,所以中间件运行时request.auth还未生成,自然无法读取。
你不需要在中间件中通过request.auth获取token,直接通过request.headers解析Authorization头提取token即可,也就是你现有中间件里写的token = request.headers['Authorization'][6:]逻辑本身是正确的,直接用这个解析出来的token查询Token表即可,不需要调用request.auth。
内容的提问来源于stack exchange,提问作者Chau Loi
相关产品推荐
相关产品推荐

