如何防止用户绕过应用通过Django DRF篡改数据?
Django DRF API 防恶意操作解决方案
一、细化权限控制,精准锁死操作范围
- 别只靠JWT的登录态,给不同用户角色分配最小必要权限。比如普通用户只能查看自己的支付记录,绝对不能碰删除操作;只有管理员才能处理他人数据。用DRF的内置权限类或自定义权限实现,示例:
from rest_framework.permissions import BasePermission class IsOwnerOrReadOnly(BasePermission): def has_object_permission(self, request, view, obj): # 只读请求对所有登录用户开放 if request.method in ['GET', 'HEAD', 'OPTIONS']: return True # 写/删操作只允许记录所有者执行 return obj.user == request.user
- 对删除支付记录这类高危操作,单独加二次验证逻辑,比如要求用户输入密码或短信验证码,在视图的
destroy方法里额外校验。
二、强化请求校验,从源头拦截无效数据
- 除了序列化器的基础校验,针对业务场景加自定义规则。比如已完成的支付记录不允许删除,提交的金额不能为负,订单号格式必须合法:
from rest_framework import serializers class PaymentRecordSerializer(serializers.ModelSerializer): def validate(self, attrs): # 删除操作时校验记录状态 if self.instance and self.context['request'].method == 'DELETE': if self.instance.status == 'completed': raise serializers.ValidationError('已完成的支付记录无法删除') # 新增/修改时校验金额合法性 if attrs.get('amount', 0) <= 0: raise serializers.ValidationError('金额必须大于0') return attrs
- 给敏感接口加限流,用DRF的
throttling限制请求频率,比如普通用户每分钟最多请求10次删除接口,防止批量恶意操作:
REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': [ 'rest_framework.throttling.UserRateThrottle' ], 'DEFAULT_THROTTLE_RATES': { 'user': '1000/day', 'delete_payment': '10/minute' # 自定义删除接口限流规则 } }
三、加固JWT凭证的安全性
- 缩短JWT的有效期,比如设置
ACCESS_TOKEN_LIFETIME = timedelta(minutes=15),用刷新令牌维持登录态,缩小凭证泄露后的风险窗口。 - 开启令牌轮换和黑名单机制,每次刷新令牌时生成新的刷新令牌,旧令牌加入黑名单,防止被复用:
JWT_AUTH = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15), 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), 'ROTATE_REFRESH_TOKENS': True, 'BLACKLIST_AFTER_ROTATION': True, }
- 强制JWT令牌只在
Authorization: Bearer <token>请求头中传输,禁止放在URL里,避免被日志或第三方工具捕获。 - 给JWT添加受众和发行方校验,确保令牌是你的服务签发,且只能用于你的API:
JWT_AUTH = { 'JWT_AUDIENCE': 'your-api-audience', 'JWT_ISSUER': 'your-domain.com', 'JWT_VERIFY_AUDIENCE': True, }
四、操作审计与异常监控
- 给敏感操作加日志,记录操作人ID、IP、时间和操作内容,出问题时能快速追溯:
import logging logger = logging.getLogger(__name__) class PaymentRecordViewSet(viewsets.ModelViewSet): def destroy(self, request, *args, **kwargs): instance = self.get_object() logger.info(f"用户{request.user.id}从IP{request.META.get('REMOTE_ADDR')}删除了支付记录{instance.id}") return super().destroy(request, *args, **kwargs)
- 监控接口的异常请求(比如校验失败、权限被拒的请求),当某IP或用户短时间内出现大量异常时,暂时封禁其访问。
五、前端辅助防护(仅为补充,不能替代后端校验)
- 前端对普通用户隐藏删除等高危操作按钮,但记住后端必须做最终校验——前端很容易被篡改绕过。
- 开启CSRF校验,确保请求来自你的前端页面,防止跨站请求伪造。
内容的提问来源于stack exchange,提问作者Simeon Thomas
相关产品推荐
相关产品推荐

