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

如何防止用户篡改浏览器中的HTML表单?Django场景防护方案

这个问题太典型了——前端的表单元素值永远是不可信的,用户随便就能用调试工具篡改,所以咱们得前端做辅助校验,后端做核心校验,后端才是真正的安全屏障。

解决思路:前端辅助+后端强校验

前端辅助校验(仅防误操作,挡不住恶意篡改)

前端校验只能给普通用户提个醒,真要搞事的人还是能改,所以别把宝压在这,但加了也没坏处:

  • 给每个复选框额外加个data-original-id属性存原始的item.id,提交前遍历选中的复选框,对比value和data-original-id是否一致,不一致就阻止提交并提示。
    模板代码修改如下:
    {% for item in sale_order_items %}
    <tr>
      <td class="text-center">
        <input type="checkbox" name="saleorderitem" value="{{item.id}}" data-original-id="{{item.id}}">
      </td>
    </tr>
    {% endfor %}
    
    配套JS代码(用jQuery举例):
    $('form').submit(function(e) {
      let isValid = true;
      $('input[name="saleorderitem"]:checked').each(function() {
        if ($(this).val() !== $(this).data('original-id')) {
          isValid = false;
          alert('请勿篡改表单数据');
          return false;
        }
      });
      if (!isValid) {
        e.preventDefault();
      }
    });
    
  • 页面加载时把所有合法的item.id存到一个前端数组里,提交AJAX前检查选中的ID是否都在这个数组里,不在就拒绝提交。

后端严格校验(安全核心,必须做)

这才是关键,不管前端怎么传,后端都要自己验证每个提交的ID是否属于当前用户有权操作的范围:

步骤1:获取当前用户的合法ID列表

先从数据库里查出该用户所有可操作的sale_order_item的ID,比如这些item属于用户自己的订单:

from django.shortcuts import get_object_or_404
from .models import SaleOrderItem, SaleOrder

def your_ajax_view(request):
    # 先拿到用户有权操作的订单(根据你的业务逻辑调整,比如用户只能操作自己创建的订单)
    target_order = get_object_or_404(SaleOrder, user=request.user, id=request.POST.get('order_id'))
    # 提取该订单下所有合法的item ID
    valid_item_ids = list(target_order.sale_order_items.values_list('id', flat=True))

步骤2:校验提交的ID合法性

拿到前端提交的ID列表后,过滤掉不在合法列表里的,直接返回错误:

# 拿到前端提交的ID并转成整数
submitted_ids = request.POST.getlist('saleorderitem')
try:
    submitted_ids = [int(id_str) for id_str in submitted_ids]
except ValueError:
    # 提交的不是合法数字,直接返回错误
    return JsonResponse({'status': 'error', 'msg': '无效参数'})

# 检查所有提交的ID是否都在合法列表中
invalid_ids = [item_id for item_id in submitted_ids if item_id not in valid_item_ids]
if invalid_ids:
    return JsonResponse({'status': 'error', 'msg': '存在无效的项目ID'})

# 到这一步的ID都是合法的,接下来可以放心处理业务逻辑
# ...

额外优化:用Django表单做校验

把校验逻辑放到Django表单里,代码更规范:

from django import forms

class SaleOrderItemForm(forms.Form):
    saleorderitem = forms.ModelMultipleChoiceField(queryset=SaleOrderItem.objects.none())

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        order_id = kwargs.pop('order_id')
        super().__init__(*args, **kwargs)
        # 动态设置可选择的item范围:当前用户该订单下的所有item
        self.fields['saleorderitem'].queryset = SaleOrderItem.objects.filter(sale_order__user=user, sale_order_id=order_id)

# 在视图中使用表单
def your_ajax_view(request):
    if request.method == 'POST':
        form = SaleOrderItemForm(
            request.POST, 
            user=request.user, 
            order_id=request.POST.get('order_id')
        )
        if form.is_valid():
            # 直接拿到合法的item对象集合
            valid_items = form.cleaned_data['saleorderitem']
            # 后续业务操作
            return JsonResponse({'status': 'success'})
        else:
            return JsonResponse({'status': 'error', 'msg': '无效的项目ID'})

核心原则

永远不要信任前端传来的任何数据,所有的权限、数据合法性校验都要在后端完成,前端只是给用户提供友好的交互和基本的防误操作提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:57:50