對訪問的頻率進行控制(固然只是在必定程度上限制,若客服端換IP,瘋狂註冊帳號沒治)python
經過獲取用戶的IP,實現一分鐘內,只能訪問三次。實際生產中應該記錄放在數據庫,或者放在緩存,或者放在文件中等等,我把記錄直接放在這裏,佔用內存不說,還有就是服務端從啓系統的話,記錄全丟失。數據庫
視圖路由與認證權限相同。api
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 from rest_framework.throttling import BaseThrottle 5 from rest_framework.throttling import SimpleRateThrottle 6 import time 7 8 VIST_RECORD = {} 9 10 11 class VisitThrottle(BaseThrottle): 12 13 def __init__(self): 14 self.history = None 15 16 def allow_request(self, request, view): 17 18 """ 19 一分鐘訪問三次最多 20 判斷是否能夠繼續訪問,頻率是否達到最大 21 :param request: 22 :param view: 23 :return: True 能夠繼續訪問 False表示訪問頻率過高要被限制 24 1.獲取用戶IP 25 """ 26 remote_addr = request.META.get('REMOTE_ADDR') 27 ctime = time.time() 28 if remote_addr not in VIST_RECORD: 29 VIST_RECORD[remote_addr] = [ctime,] 30 return True 31 history = VIST_RECORD.get(remote_addr) 32 self.history = history 33 while history and history[-1] < ctime - 60: 34 history.pop() 35 36 if len(history) < 3: 37 history.insert(0, ctime) 38 return True 39 40 def wait(self): 41 """ 42 還須要等多久才能被訪問 43 :return: 44 """ 45 ctime = time.time() 46 return 60 - (ctime - self.history[-1])
固然內置的頁幫咱們寫了這些環節,直接獲取過來用便可緩存
1 class VisitThrottle(SimpleRateThrottle): 2 scope = "Baidu" 3 4 def get_cache_key(self, request, view): 5 return self.get_ident(request) 6 7 8 class UserThrottle(SimpleRateThrottle): 9 """ 10 根據當前登陸用戶的訪問次數限制 11 """ 12 scope = "BaiduUser" 13 14 def get_cache_key(self, request, view): 15 return request.user.username
全局配置:ide
1 REST_FRAMEWORK = { 2 # 認證 3 'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.auth.Authticate', ], 4 # 'DEFAULT_AUTHENTICATION_CLASSES': [], # AnonymousUser None配置文件中有 5 # 'UNAUTHENTICATED_USER': lambda: '匿名用戶', 6 # 'UNAUTHENTICATED_USER': None, 7 # 'UNAUTHENTICATED_TOKEN': None, 8 # 權限 9 'DEFAULT_PERMISSION_CLASSES': ['api.utils.permission.Mypermission'], 10 # 節流 訪問頻率控制 11 "DEFAULT_THROTTLE_CLASSES": ['api.utils.throttle.VisitThrottle', ], 12 "DEFAULT_THROTTLE_RATES": { 13 "Baidu": '3/m', 14 "BaiduUser": '10/m', 15 } 16 17 }
局部配置:spa
1 throttle_classes = [VisitThrottle, ]
總結:本身定義節流類,在類中實現allow_request(都是這樣子若沒寫前面幾個組件都是拋錯,看基類),wait兩方法,固然wait能夠不用寫,固然看需求吧!rest
APIView的dispatch---->封裝request----->initial----->self.check_throttles(request)----->allow_request(request, self)(兩種狀況:True訪問頻率未達到最高次數,Flase訪問頻率已經達到最大的次數)code
BaseThrottle allow_request主邏輯 get_ident獲取IP wait超過次數須要多久恢復blog
SimpleRateThrottle 適用 跟我上面實現思路差很少 在settings中配置scope便可快捷內存
AnonRateThrottle 針對匿名用戶的 配置scope = 'anon'
UserRateThrottle scope = 'user'
ScopedRateThrottle scope_attr = 'throttle_scope'