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

如何为Django视图中的网页实现特定IP的DDOS防护

Django 应对DDoS攻击的IP封禁方案

问题分析

使用ratelimit库的limits装饰器时,触发的RateLimitException会导致全站崩溃,核心需求是仅封禁发起超限请求的IP,不影响正常用户访问。

解决方案

1. 捕获异常返回局部限制响应

直接捕获RateLimitException,针对超限IP返回429状态码,避免异常扩散导致全站故障。修改后的视图代码:

import ratelimit
from ratelimit import limits, RateLimitException
from django.http import HttpResponseTooManyRequests
from django.shortcuts import render

@limits(calls=5, period=10)
def home_page(request):
    try:
        user_id = request.session.get("user_id")
        authorized = user_id is not None
        return render(request, template_name="index.html", context={"authorize": authorized})
    except RateLimitException:
        return HttpResponseTooManyRequests("请求过于频繁,请稍后再试")

2. 自定义IP限流逻辑(更灵活)

如果需要更精细的控制,可基于Django缓存实现IP维度的请求计数,完全避免第三方库的异常问题:

from django.core.cache import cache
from django.http import HttpResponseTooManyRequests
from django.shortcuts import render

def home_page(request):
    # 获取客户端IP
    client_ip = request.META.get('REMOTE_ADDR')
    cache_key = f"rate_limit_{client_ip}"
    
    # 获取当前请求次数,默认0
    request_count = cache.get(cache_key, 0)
    
    if request_count >= 5:
        return HttpResponseTooManyRequests("请求过于频繁,请稍后再试")
    
    # 更新缓存:计数+1,有效期10秒
    cache.set(cache_key, request_count + 1, 10)
    
    user_id = request.session.get("user_id")
    authorized = user_id is not None
    return render(request, template_name="index.html", context={"authorize": authorized})

3. 进阶优化建议

  • 前端配合添加请求间隔限制,减少无效请求到达后端
  • 若有服务器权限,优先在Nginx层面配置IP限流,性能远优于Python代码层面的控制
  • 针对持续恶意攻击的IP,可编写Django中间件实现IP黑名单机制,直接拦截请求

内容的提问来源于stack exchange,提问作者Can't get my programs to work

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:43:17