Django 限制訪問頻率的思路詳解
阿新 • • 發佈:2020-01-09
最近做了一個系統由於部分介面需要進行耗時操作,因而不希望使用者進行頻繁訪問,需要進行訪問頻率限制。如果要自己實現一個訪問限制功能相對來說也不會太複雜,並且網上有各種程式碼可以參考。如果自己不想實現這個程式碼可以使用Django Ratelimit 。
Django Ratelimit is a ratelimiting decorator for Django views. https://travis-ci.org/jsocol/django-ratelimit.png?branch=master Code: https://github.com/jsocol/django-ratelimit License: Apache Software License Issues: https://github.com/jsocol/django-ratelimit/issues Documentation: http://django-ratelimit.readthedocs.org/
使用方法也相對來說比較簡單:
@ratelimit(key='ip',rate='5/m') def myview(request): # Will be true if the same IP makes more than 5 POST # requests/minute. was_limited = getattr(request,'limited',False) return HttpResponse() @ratelimit(key='ip',rate='5/m',block=True) def myview(request): # If the same IP makes >5 reqs/min,will raise Ratelimited return HttpResponse() @ratelimit(key='post:username',method=['GET','POST']) def login(request): # If the same username is used >5 times/min,this will be True. # The `username` value will come from GET or POST,determined by the # request method. was_limited = getattr(request,False) return HttpResponse() @ratelimit(key='post:username',rate='5/m') @ratelimit(key='post:tenant',rate='5/m') def login(request): # Use multiple keys by stacking decorators. return HttpResponse() @ratelimit(key='get:q',rate='5/m') @ratelimit(key='post:q',rate='5/m') def search(request): # These two decorators combine to form one rate limit: the same search # query can only be tried 5 times a minute,regardless of the request # method (GET or POST) return HttpResponse() @ratelimit(key='ip',rate='4/h') def slow(request): # Allow 4 reqs/hour. return HttpResponse() rate = lambda r: None if request.user.is_authenticated else '100/h' @ratelimit(key='ip',rate=rate) def skipif1(request): # Only rate limit anonymous requests return HttpResponse() @ratelimit(key='user_or_ip',rate='10/s') @ratelimit(key='user_or_ip',rate='100/m') def burst_limit(request): # Implement a separate burst limit. return HttpResponse() @ratelimit(group='expensive',key='user_or_ip',rate='10/h') def expensive_view_a(request): return something_expensive() @ratelimit(group='expensive',rate='10/h') def expensive_view_b(request): # Shares a counter with expensive_view_a return something_else_expensive() @ratelimit(key='header:x-cluster-client-ip') def post(request): # Uses the X-Cluster-Client-IP header value. return HttpResponse() @ratelimit(key=lambda r: r.META.get('HTTP_X_CLUSTER_CLIENT_IP',r.META['REMOTE_ADDR']) def myview(request): # Use `X-Cluster-Client-IP` but fall back to REMOTE_ADDR. return HttpResponse()
不過需要注意如果和django rest framwork一起使用的話,要將Ratelimit 裝飾器放到第一行,如下:
@ratelimit(key='user',rate='1/3s',block=True,method=ratelimit.ALL) @api_view(['POST','GET']) @csrf_exempt def api_get_level(request):
否則會導致如下的錯誤資訊:
IndexError at /rest-api/level/ tuple index out of range Request Method: GET Request URL: http://192.168.1.195:8006/rest-api/level/ Django Version: 2.2.7 Exception Type: IndexError Exception Value: tuple index out of range Exception Location: F:\PyCharmProjects\server\venv\lib\site-packages\ratelimit\decorators.py in _wrapped,line 23 Python Executable: F:\PyCharmProjects\server\venv\Scripts\python.exe Python Version: 3.7.5 Python Path: ['F:\\PyCharmProjects\\server\\TaichiGameServer','I:\\Python37-64\\python37.zip','I:\\Python37-64\\DLLs','I:\\Python37-64\\lib','I:\\Python37-64','F:\\PyCharmProjects\\server\\venv','F:\\PyCharmProjects\\server\\venv\\lib\\site-packages','F:\\PyCharmProjects\\server\\venv\\lib\\site-packages\\setuptools-39.1.0-py3.7.egg'] Server time: Tue,24 Dec 2019 09:49:01 +0800 Traceback (most recent call last): File "F:\PyCharmProjects\server\venv\lib\site-packages\django\core\handlers\exception.py",line 34,in inner response = get_response(request) File "F:\PyCharmProjects\server\venv\lib\site-packages\django\core\handlers\base.py",line 115,in _get_response response = self.process_exception_by_middleware(e,request) File "F:\PyCharmProjects\server\venv\lib\site-packages\django\core\handlers\base.py",line 113,in _get_response response = wrapped_callback(request,*callback_args,**callback_kwargs) File "F:\PyCharmProjects\server\venv\lib\site-packages\django\views\decorators\csrf.py",line 54,in wrapped_view return view_func(*args,**kwargs) File "F:\PyCharmProjects\server\venv\lib\site-packages\django\views\generic\base.py",line 71,in view return self.dispatch(request,*args,**kwargs) File "F:\PyCharmProjects\server\venv\lib\site-packages\rest_framework\views.py",line 505,in dispatch response = self.handle_exception(exc) File "F:\PyCharmProjects\server\venv\lib\site-packages\rest_framework\views.py",line 465,in handle_exception self.raise_uncaught_exception(exc) File "F:\PyCharmProjects\server\venv\lib\site-packages\rest_framework\views.py",line 476,in raise_uncaught_exception raise exc File "F:\PyCharmProjects\server\venv\lib\site-packages\rest_framework\views.py",line 502,in dispatch response = handler(request,**kwargs) File "F:\PyCharmProjects\server\venv\lib\site-packages\rest_framework\decorators.py",line 50,in handler return func(*args,**kwargs) File "F:\PyCharmProjects\server\venv\lib\site-packages\django\views\decorators\csrf.py",**kwargs) File "F:\PyCharmProjects\server\venv\lib\site-packages\ratelimit\decorators.py",line 23,in _wrapped request = args[1] IndexError: tuple index out of range
總結
以上所述是小編給大家介紹的Django 限制訪問頻率的思路詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對我們網站的支援!
如果你覺得本文對你有幫助,歡迎轉載,煩請註明出處,謝謝!