中间件方式

中间件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import time
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
# 访问IP池
visit_ip_pool = {}
class RequestBlockingMiddleware(MiddlewareMixin):
def process_request(self,request):
# 获取访问者IP
ip=request.META.get("REMOTE_ADDR")
# 获取访问当前时间
visit_time=time.time()
# 判断如果访问IP不在池中,就将访问的ip时间插入到对应ip的key值列表,如{"127.0.0.1":[时间1]}
if ip not in visit_ip_pool:
visit_ip_pool[ip]=[visit_time]
return None
# 然后在从池中取出时间列表
history_time = visit_ip_pool.get(ip)
# 循环判断当前ip的时间列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
while history_time and visit_time-history_time[-1]>60:
history_time.pop()
# 如果访问次数小于10次就将访问的ip时间插入到对应ip的key值列表的第一位置,如{"127.0.0.1":[时间2,时间1]}
print(history_time)
if len(history_time)<10:
history_time.insert(0, visit_time)
return None
else:
# 如果大于10次就禁止访问
return HttpResponse("访问过于频繁,还需等待%s秒才能继续访问"%int(60-(visit_time-history_time[-1])))

setting中配置

1
2
3
4
5
6
7
8
9
10
11
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
# ip访问限制
'service.utils.RequestBlockingMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

django-throttle-requests模块

安装:
pip install django-throttle-requests

settings.py配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
THROTTLE_ZONES = {
# 限制请求频率 10次/分
'default': {
'VARY':'throttle.zones.RemoteIP',
'NUM_BUCKETS':2, # Number of buckets worth of history to keep. Must be at least 2
'BUCKET_INTERVAL':1 * 60, # Period of time to enforce limits.
'BUCKET_CAPACITY':10, # Maximum number of requests allowed within BUCKET_INTERVAL
},
# 限制请求频率 50次/小时
'order': {
'VARY':'throttle.zones.RemoteIP',
'NUM_BUCKETS':2, # Number of buckets worth of history to keep. Must be at least 2
'BUCKET_INTERVAL':60 * 60, # Period of time to enforce limits.
'BUCKET_CAPACITY':50, # Maximum number of requests allowed within BUCKET_INTERVAL
},
}

THROTTLE_BACKEND = 'throttle.backends.cache.CacheBackend'

# Force throttling when DEBUG=True
THROTTLE_ENABLED = True

视图中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from throttle.decorators import throttle


@throttle(zone='default')
def pay_query(request):
...
```---
title: python中基于django对IP访问频率限制
date: 2023-07-17 14:51:00
updated: 2023-07-17 14:51:58
categories: Python
tags:
-
id: django-ip
cover:
---
# 中间件方式
## 中间件代码
```python
import time
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
# 访问IP池
visit_ip_pool = {}
class RequestBlockingMiddleware(MiddlewareMixin):
def process_request(self,request):
# 获取访问者IP
ip=request.META.get("REMOTE_ADDR")
# 获取访问当前时间
visit_time=time.time()
# 判断如果访问IP不在池中,就将访问的ip时间插入到对应ip的key值列表,如{"127.0.0.1":[时间1]}
if ip not in visit_ip_pool:
visit_ip_pool[ip]=[visit_time]
return None
# 然后在从池中取出时间列表
history_time = visit_ip_pool.get(ip)
# 循环判断当前ip的时间列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
while history_time and visit_time-history_time[-1]>60:
history_time.pop()
# 如果访问次数小于10次就将访问的ip时间插入到对应ip的key值列表的第一位置,如{"127.0.0.1":[时间2,时间1]}
print(history_time)
if len(history_time)<10:
history_time.insert(0, visit_time)
return None
else:
# 如果大于10次就禁止访问
return HttpResponse("访问过于频繁,还需等待%s秒才能继续访问"%int(60-(visit_time-history_time[-1])))

setting中配置

1
2
3
4
5
6
7
8
9
10
11
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
# ip访问限制
'service.utils.RequestBlockingMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

django-throttle-requests模块

安装:
pip install django-throttle-requests

settings.py配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
THROTTLE_ZONES = {
# 限制请求频率 10次/分
'default': {
'VARY':'throttle.zones.RemoteIP',
'NUM_BUCKETS':2, # Number of buckets worth of history to keep. Must be at least 2
'BUCKET_INTERVAL':1 * 60, # Period of time to enforce limits.
'BUCKET_CAPACITY':10, # Maximum number of requests allowed within BUCKET_INTERVAL
},
# 限制请求频率 50次/小时
'order': {
'VARY':'throttle.zones.RemoteIP',
'NUM_BUCKETS':2, # Number of buckets worth of history to keep. Must be at least 2
'BUCKET_INTERVAL':60 * 60, # Period of time to enforce limits.
'BUCKET_CAPACITY':50, # Maximum number of requests allowed within BUCKET_INTERVAL
},
}

THROTTLE_BACKEND = 'throttle.backends.cache.CacheBackend'

# Force throttling when DEBUG=True
THROTTLE_ENABLED = True

视图中使用

1
2
3
4
5
6
from throttle.decorators import throttle


@throttle(zone='default')
def pay_query(request):
...