求助:Django Rest Framework函数视图缓存致权限类失效
Django DRF 函数视图缓存与权限类冲突的修复方案
问题根源
你遇到的问题是装饰器执行顺序导致的:@cache_page放在最外层时,会直接缓存权限验证通过后的完整响应。后续请求会直接返回缓存结果,完全跳过了@permission_classes和api_view的权限校验逻辑,导致权限规则失效。
修复方法
方法1:调整装饰器执行顺序(推荐)
将@cache_page移到权限相关装饰器的后面,让每次请求先经过权限验证,验证通过后才会读取缓存或生成新的响应缓存。
修改后的代码:
@api_view(['GET']) @permission_classes((APIKeyPermission,)) @cache_page(3600) def function_based_view(request): # function-based view code here...
- 原理:装饰器的执行顺序是从下到上(靠近函数的先执行),现在权限验证会优先于缓存逻辑执行,只有权限通过的请求才会触发缓存操作。
- 优缺点:实现最简单,完全保证权限校验不被跳过;唯一的小代价是每次请求都要执行权限验证,但权限校验的性能开销通常远低于视图业务逻辑的开销,对整体性能影响极小。
方法2:自定义缓存键,包含权限标识
如果希望保留缓存的同时,让不同权限的请求拥有独立缓存,可以自定义缓存键生成函数,将权限相关信息(如API Key的哈希值)加入缓存键中。
示例代码:
import hashlib def permission_based_cache_key(request, *args, **kwargs): # 从请求头获取API Key(根据你的实际权限类逻辑调整) api_key = request.META.get('HTTP_X_API_KEY', '') # 对API Key做哈希处理,避免敏感信息直接暴露在缓存键中 hashed_key = hashlib.sha256(api_key.encode()).hexdigest() # 生成包含权限标识的缓存键 return f"fbv_cache_{hashed_key}_{request.path}" @cache_page(3600, key_func=permission_based_cache_key) @api_view(['GET']) @permission_classes((APIKeyPermission,)) def function_based_view(request): # function-based view code here...
- 原理:不同权限的请求会生成不同的缓存键,缓存内容相互隔离,同时权限验证仍会在缓存之前执行。
- 优缺点:可以缓存不同权限用户的响应,减少重复计算;但需要额外处理缓存键的生成逻辑,且要注意敏感信息的安全处理(比如哈希API Key)。
方法3:使用自定义中间件前置权限验证
如果需要更全局的控制,可以编写一个中间件,在Django的缓存中间件之前执行权限验证,确保所有请求先过权限关,再触发缓存逻辑。
示例中间件:
from django.http import HttpResponseForbidden from rest_framework.permissions import APIKeyPermission class PermissionBeforeCacheMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 仅对目标视图的GET请求做权限验证 if request.path == "/your-view-path/" and request.method == "GET": permission = APIKeyPermission() if not permission.has_permission(request, None): return HttpResponseForbidden("Permission denied") response = self.get_response(request) return response
然后将这个中间件添加到settings.py的MIDDLEWARE列表中,且要放在django.middleware.cache.UpdateCacheMiddleware之前。
- 优缺点:适合全局统一处理;但需要精确匹配目标视图,逻辑相对复杂,不推荐用于单个视图的场景。
内容的提问来源于stack exchange,提问作者stackunderflow
相关产品推荐
相关产品推荐

