1. 程式人生 > 程式設計 >Django 限制訪問頻率的思路詳解

Django 限制訪問頻率的思路詳解

最近做了一個系統由於部分介面需要進行耗時操作,因而不希望使用者進行頻繁訪問,需要進行訪問頻率限制。如果要自己實現一個訪問限制功能相對來說也不會太複雜,並且網上有各種程式碼可以參考。如果自己不想實現這個程式碼可以使用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 限制訪問頻率的思路詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對我們網站的支援!
如果你覺得本文對你有幫助,歡迎轉載,煩請註明出處,謝謝!