Django UpdateView如何防止URL篡改?避免恶意修改数据
解决Django UpdateView中恶意用户篡改PK修改他人数据的问题
针对你遇到的已登录用户可通过修改URL中的PK值来修改他人联系人记录的问题,除了会话存储UUID的方式,还有以下几种贴合Django生态的解决方案:
1. 重写get_queryset方法过滤用户可见数据
通过限制视图的查询集仅包含当前用户拥有的联系人,即使恶意用户篡改PK,视图会因找不到对应对象返回404错误,从根源上阻止越权访问。
class ContactUpdate(UpdateView): model = Contacts form_class = ContactForm template_name = 'contact_detail.html' success_url = reverse_lazy('test:contacts-list') def get_queryset(self): # 假设Contacts模型有一个关联到当前用户的外键字段(例如user) return super().get_queryset().filter(user=self.request.user)
2. 重写get_object方法做权限校验
在获取要修改的对象时,直接验证当前用户是否拥有该对象的修改权限,若无权则抛出403禁止访问异常。
from django.core.exceptions import PermissionDenied class ContactUpdate(UpdateView): model = Contacts form_class = ContactForm template_name = 'contact_detail.html' success_url = reverse_lazy('test:contacts-list') def get_object(self, queryset=None): obj = super().get_object(queryset=queryset) # 验证当前用户是否为联系人的所有者 if obj.user != self.request.user: raise PermissionDenied return obj
3. 使用UserPassesTestMixin混入类
利用Django提供的权限校验混入类,统一处理视图的权限逻辑,代码更符合Django类视图规范。
from django.contrib.auth.mixins import UserPassesTestMixin class ContactUpdate(UserPassesTestMixin, UpdateView): model = Contacts form_class = ContactForm template_name = 'contact_detail.html' success_url = reverse_lazy('test:contacts-list') def test_func(self): # 获取当前要修改的对象 contact = self.get_object() # 返回布尔值表示用户是否有权限 return contact.user == self.request.user
4. 在form_valid方法中追加权限校验
如果需要在表单验证通过后再做权限检查(适合更复杂的权限场景),可以重写form_valid方法:
from django.core.exceptions import PermissionDenied class ContactUpdate(UpdateView): model = Contacts form_class = ContactForm template_name = 'contact_detail.html' success_url = reverse_lazy('test:contacts-list') def form_valid(self, form): contact = self.get_object() if contact.user != self.request.user: raise PermissionDenied return super().form_valid(form)
注意事项
以上示例均假设你的Contacts模型包含一个关联到User模型的外键字段(命名为user),如果你的权限逻辑是基于其他规则(比如用户组、角色),只需修改对应的校验条件即可。
内容的提问来源于stack exchange,提问作者AndyP1970
相关产品推荐
相关产品推荐

