1. 程式人生 > >Django-Rest frameworw使用者訪問次數/頻率限制

Django-Rest frameworw使用者訪問次數/頻率限制

一、示例展示

=============******=============

            1、BaseThrottle原類

            2、基於使用者IP限制訪問頻率 (瞭解)

            3、基於使用者IP顯示訪問頻率(利於Django快取) # 經常使用

            4、匿名時用IP限制+登入時用Token限制

=============******=============

全域性使用:

in settings.py

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'api.utils.throttles.throttles.LuffyAnonRateThrottle',
        'api.utils.throttles.throttles.LuffyUserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/day',
        'user': '10/day',
        'luffy_anon': '10/m',
        'luffy_user': '20/m',
    },
}

1、BaseThrottle原類

class BaseThrottle(object):
	"""
    Rate throttling of requests.
    """

    def allow_request(self, request, view): #判斷是否允許請求,來訪問 
        """
        Return `True` if the request should be allowed, `False` otherwise.
        """
        raise NotImplementedError('.allow_request() must be overridden')

    def get_ident(self, request):  # 獲取請求的IP,
        xff = request.META.get('HTTP_X_FORWARDED_FOR')
        remote_addr = request.META.get('REMOTE_ADDR')
        num_proxies = api_settings.NUM_PROXIES

        if num_proxies is not None:
            if num_proxies == 0 or xff is None:
                return remote_addr
            addrs = xff.split(',')
            client_addr = addrs[-min(num_proxies, len(addrs))]
            return client_addr.strip()

        return ''.join(xff.split()) if xff else remote_addr

    def wait(self):  # 等待時間設定
        """
        Optionally, return a recommended number of seconds to wait before
        the next request.
        """
        return None

2、基於使用者IP限制訪問頻率 (瞭解)

in  url.py
	from django.conf.urls import url, include
	from web.views import TestView

	urlpatterns = [
	    url(r'^test/', TestView.as_view()),
	]
in views.py
	#!/usr/bin/env python
	# -*- coding:utf-8 -*-
	import time
	from rest_framework.views import APIView
	from rest_framework.response import Response

	from rest_framework import exceptions
	from rest_framework.throttling import BaseThrottle
	from rest_framework.settings import api_settings

	# 儲存訪問記錄
	RECORD = {
	    '使用者IP': [12312139, 12312135, 12312133, ]
	}


	class TestThrottle(BaseThrottle):
            '''仿照SimpleRateThrottle這個類,做簡單化處理,看懂後在看SimpleRateThrottle就很簡單了'''
	    ctime = time.time

	    def get_ident(self, request):
	        """
	        根據使用者IP和代理IP,當做請求者的唯一IP
	        """
	        xff = request.META.get('HTTP_X_FORWARDED_FOR')
	        remote_addr = request.META.get('REMOTE_ADDR')
	        num_proxies = api_settings.NUM_PROXIES

	        if num_proxies is not None:
	            if num_proxies == 0 or xff is None:
	                return remote_addr
	            addrs = xff.split(',')
	            client_addr = addrs[-min(num_proxies, len(addrs))]
	            return client_addr.strip()

	        return ''.join(xff.split()) if xff else remote_addr

	    def allow_request(self, request, view):
	        """
	        是否仍然在允許範圍內
	        :return: True,表示可以通過;False表示已超過限制,不允許訪問
	        """
	        # 獲取使用者唯一標識(如:IP)

	        # 允許一分鐘訪問10次
	        num_request = 10
	        time_request = 60

	        now = self.ctime()
	        ident = self.get_ident(request)
	        self.ident = ident
	        if ident not in RECORD:
	            RECORD[ident] = [now, ]
	            return True
	        history = RECORD[ident]
	        while history and history[-1] <= now - time_request:
	            history.pop()
	        if len(history) < num_request:
	            history.insert(0, now)
	            return True

	    def wait(self):
	        """
	        多少秒後可以允許繼續訪問
	        """
	        last_time = RECORD[self.ident][0]
	        now = self.ctime()
	        return int(60 + last_time - now)


	class TestView(APIView):
	    throttle_classes = [TestThrottle, ]

	    def get(self, request, *args, **kwargs):
	        # self.dispatch
	        print(request.user)
	        print(request.auth)
	        return Response('GET請求,響應內容')

	    def post(self, request, *args, **kwargs):
	        return Response('POST請求,響應內容')

	    def put(self, request, *args, **kwargs):
	        return Response('PUT請求,響應內容')

	    def throttled(self, request, wait):
	        """
	        訪問次數被限制時,定製錯誤資訊
	        """

	        class Throttled(exceptions.Throttled):
	            default_detail = '請求被限制.'
	            extra_detail_singular = '請 {wait} 秒之後再重試.'
	            extra_detail_plural = '請 {wait} 秒之後再重試.'

	        raise Throttled(wait)

3、基於使用者IP顯示訪問頻率(利於Django快取) # 經常使用

in settings.py
	REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'test_scope': '10/m',  # s 秒  h 小時 d 天 m 分鐘 等等 原始碼通過/切割,判斷右邊首位是什麼來判斷時間單位
    },
}

in url.py
	from django.conf.urls import url, include
	from web.views import TestView

	urlpatterns = [
	    url(r'^test/', TestView.as_view()),
	]

in  views.py
	#!/usr/bin/env python
	# -*- coding:utf-8 -*-
	from rest_framework.views import APIView
	from rest_framework.response import Response

	from rest_framework import exceptions
	from rest_framework.throttling import SimpleRateThrottle


	class TestThrottle(SimpleRateThrottle):

	    scope = 'test_scope'   # 顯示頻率的Key,在配置檔案裡需要有個跟這個同名

	    def get_cache_key(self, request, view):
	        return self.get_ident(request) # 獲取請求IP


	class TestView(APIView):
	    throttle_classes = [TestThrottle, ]

	    def get(self, request, *args, **kwargs):
	        # self.dispatch
	        print(request.user)
	        print(request.auth)
	        return Response('GET請求,響應內容')

	    def post(self, request, *args, **kwargs):
	        return Response('POST請求,響應內容')

	    def put(self, request, *args, **kwargs):
	        return Response('PUT請求,響應內容')

	    def throttled(self, request, wait):
	        """
	        訪問次數被限制時,定製錯誤資訊
	        """

	        class Throttled(exceptions.Throttled):
	            default_detail = '請求被限制.'
	            extra_detail_singular = '請 {wait} 秒之後再重試.'
	            extra_detail_plural = '請 {wait} 秒之後再重試.'

	        raise Throttled(wait)
4、匿名時用IP限制+登入時用Token限制
in settings.py
	REST_FRAMEWORK = {
	    'UNAUTHENTICATED_USER': None,
	    'UNAUTHENTICATED_TOKEN': None,
	    'DEFAULT_THROTTLE_RATES': {
	        'luffy_anon': '10/m',
	        'luffy_user': '20/m',
	    },
	}
in url.py
	from django.conf.urls import url, include
	from web.views.s3_throttling import TestView

	urlpatterns = [
	    url(r'^test/', TestView.as_view()),
	]
in views.py
	#!/usr/bin/env python
	# -*- coding:utf-8 -*-
	from rest_framework.views import APIView
	from rest_framework.response import Response

	from rest_framework.throttling import SimpleRateThrottle


	class LuffyAnonRateThrottle(SimpleRateThrottle):
	    """
	    匿名使用者,根據IP進行限制
	    """
	    scope = "luffy_anon"

	    def get_cache_key(self, request, view):
	        # 使用者已登入,則跳過 匿名頻率限制
	        if request.user:
	            return None

	        return self.cache_format % {
	            'scope': self.scope,
	            'ident': self.get_ident(request)
	        }


	class LuffyUserRateThrottle(SimpleRateThrottle):
	    """
	    登入使用者,根據使用者token限制
	    """
	    scope = "luffy_user"

	    def get_ident(self, request):
	        """
	        認證成功時:request.user是使用者物件;request.auth是token物件
	        :param request: 
	        :return: 
	        """
	        # return request.auth.token
	        return "user_token"

	    def get_cache_key(self, request, view):
	        """
	        獲取快取key
	        :param request: 
	        :param view: 
	        :return: 
	        """
	        # 未登入使用者,則跳過 Token限制
	        if not request.user:
	            return None

	        return self.cache_format % {
	            'scope': self.scope,
	            'ident': self.get_ident(request)
	        }


	class TestView(APIView):
	    throttle_classes = [LuffyUserRateThrottle, LuffyAnonRateThrottle, ]

	    def get(self, request, *args, **kwargs):
	        # self.dispatch
	        print(request.user)
	        print(request.auth)
	        return Response('GET請求,響應內容')

	    def post(self, request, *args, **kwargs):
	        return Response('POST請求,響應內容')

	    def put(self, request, *args, **kwargs):
	        return Response('PUT請求,響應內容')

相關推薦

Django-Rest frameworw使用者訪問次數/頻率限制

一、示例展示=============******=============            1、BaseThrottle原類            2、基於使用者IP限制訪問頻率 (瞭解)            3、基於使用者IP顯示訪問頻率(利於Django快取)

Django-Rest frameworw之解析器

一、解析器        根據請求頭 content-type 選擇對應的解析器就請求體內容進行處理。        注意:個別特殊的值可以通過Django的request物件 request._request 來進行獲取media_type = None # applica

Django-Rest frameworw認證和許可權

一、認證已封裝好的類 from rest_framework.authentication import BaseAuthentication class BaseAuthentication(object): def authenticate(self, reques

Django-Rest frameworw之路由系統

路由系統============******============                        一、 自定義路由                        二、 半自動路由                        三、 全自動路由========

Django rest framework 限制訪問頻率(原始碼分析三)

  基於  當用發出請求時 首先執行dispatch函式,當執行當第二部時: #2.處理版本資訊 處理認證資訊 處理許可權資訊 對使用者的訪問頻率進行限制 self.initial(request, *args, **kwargs)

Django REST Framework之頻率限制

開放平臺的API介面呼叫需要限制其頻率,以節約伺服器資源和避免惡意的頻繁呼叫 使用 自定義頻率限制元件:utils/thottle.py class MyThrottle(BaseThrottle): def __init__(self): self.history

Django Rest Framework源碼剖析(三)-----頻率控制

BE elf attr 基本使用 fix ddr integer als min 一、簡介 承接上篇文章Django Rest Framework源碼剖析(二)-----權限,當服務的接口被頻繁調用,導致資源緊張怎麽辦呢?當然或許有很多解決辦法,比如:負載均衡、

DRF之限制單位時間訪問次數

參數 sse auth resp ews quest anon http period 1、節流源碼流程: # step 1 def dispatch(self, request, *args, **kwargs): try: self.initia

自定義訪問頻率限制的中介軟體

自定義訪問頻率限制的中介軟體 首先在自定義中介軟體的檔案中匯入 from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse from django.conf import s

Django 中介軟體實現使用者認證與IP頻率限制

1.URL訪問過濾 通過裝飾器進行使用者認證非常方便,但是在新增部分需要認證的功能時,就需要再次新增裝飾器,如果通過中介軟體來實現,就不需要再進行新增的操作. import re LOGIN_URL = '/login/' class MyLogin(MiddlewareMixin): def p

Django 統計網站訪問次數訪問 ip 、訪問端點及次數

個人部落格:http://www.iamnancy.top 有時候寫完部落格,想知道網站每天的訪問量,都有哪些人訪問,都是來自什麼地方的訪客,都訪問了哪些端點。 效果如下: 編寫 blog/models.py # 訪問網站的 ip 地址、端點和次數 class User

雲展網教程 | 關於訪問次數限制

1 、什麼是訪問次數? 訪問次數是指一個賬號的所有書所有讀者的訪問總次數,在個人中心可以檢視訪問次數數量等。只要讀者開啟您的書籍閱讀,除了以下幾種情況外,都將計算入訪問次數。 • 從雲展網首頁或者展廳進入的訪問(PC端)不計入總數; • 登入賬號上傳書籍視窗預覽,訪問的次數不計入總數

雲展網教程 | 設定單本書籍訪問次數限制

1 什麼是單本書籍訪問次數限制? 在使用者現有的訪問次數總量上給已上傳的一本或者多本書分配指定的訪問量;便於廣告或者媒體公司根據客戶情況分配指定的訪問量。 2 哪些會員支援這個功能? 此功能僅限於黃金版以及白金版會員使用。 3 如何設定? 1)找到需要限制次數的書籍,點選相應的限制流

新浪微博開放平臺API訪問頻率限制解決方法

新浪微博開放平臺API的呼叫和TWITTER介面一樣,都是受限的,以小時為單位進行限定。   他有兩個限制原則 1.使用者不登入基於IP的限制,每小時1000次 2.使用者登入了基於使用者的限制,每小時1000次   如果應用是使用者不登入的那麼就是對IP

nginx限制每個ip訪問頻率和併發量

http{ ... limit_req_zone$binary_remote_addr zone=allips:10m rate=20r/s; 解釋:#定義一個名為allips的limit_req_zone用來儲存session,大小是10M記憶體,

Nginx中如何限制某個IP同一時間段的訪問次數

如何設定能限制某個IP某一時間段的訪問次數是一個讓人頭疼的問題,特別面對惡意的ddos攻擊的時候。其中CC攻擊(Challenge Collapsar)是DDOS(分散式拒絕服務)的一種,也是一種常見的網站攻擊方法,攻擊者通過代理伺服器或者肉雞向向受害主機不停地發大量資料

設定時間段內同一IP的訪問次數限制和同一IP的操作次數限制

設定時間段內同一IP的訪問次數限制: 主要使用httpservlet和timer task來記錄並且執行定時(時間段比如60s)訪問次數(比如最大為10),然後超出則丟擲異常。 同一IP的操作次數限制: 主要用資料庫(ip,時間計算,操作次數,備註資訊),來實現限制

nginx限制某個IP同一時間段的訪問次數

如何設定能限制某個IP某一時間段的訪問次數是一個讓人頭疼的問題,特別面對惡意的ddos攻擊的時候。其中CC攻擊(Challenge Collapsar)是DDOS(分散式拒絕服務)的一種,也是一種常見的網站攻擊方法,攻擊者通過代理伺服器或者肉雞向向受害主機不停地發大量資料包

基於中間件訪問頻率限制 每分鐘時間間隔最多訪問3次

頻率 cor while proc process ces war esp n) 同一個IP 1分鐘時間間隔只能訪問三次 1. 拿到用戶請求的IP 2. 當前請求的時間 3. 記錄訪問的歷史 VISIT_RECORD ={ ‘ip‘:[] }

Django REST framework基礎:認證、權限、限制

bsp request history inf 機制 length pre div view 認證、權限和限制 身份驗證是將傳入請求與一組標識憑據(例如請求來自的用戶或其簽名的令牌)相關聯的機制。然後 權限 和 限制 組件決定是否拒絕這個請求。 簡單來說就是: