Django中比较owner_id与request.user.id做鉴权是否安全?
关于Django DRF 视图集get_queryset鉴权逻辑的安全性解答
核心结论
你当前写的get_queryset中用owner_id=self.request.user.id过滤数据的逻辑本身是安全的,用户不可能通过Postman或其他任意请求工具修改request.user.id来拉取其他用户的Meal数据。
安全原因说明
Django的request.user对象完全由服务端认证逻辑生成:
- 如果你用的是Session认证,
request.user是通过请求携带的Cookie中session_id在服务端查询对应登录用户得到的 - 如果你用的是Token类认证,
request.user是通过请求头里的token在服务端校验后匹配到的用户
整个过程用户无法通过自定义请求参数、请求头、请求体内容来篡改request.user的属性值,request.user.id完全由服务端管控,不受客户端请求内容的影响。
额外需要补充的安全优化点
虽然你当前的过滤逻辑是安全的,但现有代码存在两个可优化的安全点,避免其他越权风险:
- 增加登录权限限制
你当前的视图集没有配置权限校验,未登录的匿名用户也可以访问接口,此时request.user是匿名用户对象,id为None,查询会返回空列表或者抛出错误,建议给视图集增加登录限制:
from rest_framework import permissions class MealViewSet(viewsets.ModelViewSet): queryset = Meal.objects.all() serializer_class = MealSerializer # 新增权限类,只有登录用户可访问 permission_classes = [permissions.IsAuthenticated] def get_queryset(self): return Meal.objects.filter(owner_id=self.request.user.id)
- 新增创建时的owner自动赋值逻辑
你当前没有重写创建数据的逻辑,如果用户在POST请求里主动传owner_id参数,序列化器会直接保存为用户传入的值,导致可以把Meal创建到其他用户名下,建议新增perform_create方法强制指定owner为当前登录用户:
def perform_create(self, serializer): # 强制覆盖owner为当前登录用户,无视客户端传入的owner参数 serializer.save(owner=self.request.user)
- 可选优化:序列化器移除owner字段
如果你不需要返回所属用户信息,可以把序列化器的fields改成显式声明,排除owner字段,避免暴露用户ID信息,属于非必要的最佳实践。
内容的提问来源于stack exchange,提问作者KBSN
相关产品推荐
相关产品推荐

