限流與過(guò)濾
當(dāng)前,我們的 Restful Web API 不僅能夠提供客戶端需要的資源,還實(shí)現(xiàn)了認(rèn)證和權(quán)限,可以保證數(shù)據(jù)的安全。大家在日常中一定有過(guò)這樣的經(jīng)歷,有些網(wǎng)站免費(fèi)用戶一天只能免費(fèi)觀看 3 部視頻,超過(guò)就要付費(fèi),否則無(wú)法觀看,另外,如果想找到 2020 年上映的全部電影,只需在檢索時(shí)選中想要的年份就可以。那么我們搭建的 Restful Web API 能實(shí)現(xiàn)類(lèi)似的功能嗎?當(dāng)然可以,這就涉及到了限流與過(guò)濾,接下來(lái),我們就帶領(lǐng)大家,一起實(shí)現(xiàn)這兩個(gè)功能。
1.限流的使用方法
有時(shí),為了防止惡意訪問(wèn),或減輕服務(wù)器壓力,我們需要對(duì)用戶的訪問(wèn)頻率進(jìn)行限制。我們可在配置文件中,使用DEFAULT_THROTTLE_CLASSES
和 DEFAULT_THROTTLE_RATES
進(jìn)行全局配置,
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day', # 匿名用戶每天可訪問(wèn)100次
'user': '1000/day' # 通過(guò)認(rèn)證的用戶每天可訪問(wèn)1000次
}
}
DEFAULT_THROTTLE_RATES
可以使用 second
, minute
, hour
或day
來(lái)指明周期。也可以在具體視圖中通過(guò) throttle_classess 屬性來(lái)配置,如
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
class ExampleView(APIView):
throttle_classes = (UserRateThrottle,)
...
2. Django Rest framework為我們提供的限流類(lèi)
2.1 AnonRateThrottle
限制所有匿名未認(rèn)證用戶,不同用戶的區(qū)分通過(guò)識(shí)別用戶 IP 實(shí)現(xiàn)。使用DEFAULT_THROTTLE_RATES['anon']
來(lái)設(shè)置頻率限制。
2.2 UserRateThrottle
限制認(rèn)證用戶,使用 User id 來(lái)區(qū)分不同用戶。使用 DEFAULT_THROTTLE_RATES['user']
來(lái)設(shè)置頻率限制。
2.3 ScopedRateThrottle
限制用戶對(duì)于每個(gè)視圖的訪問(wèn)頻次,使用 ip 或 user id 區(qū)分不同用戶。
例如:
class ContactListView(APIView):
throttle_scope = 'contacts'
...
class ContactDetailView(APIView):
throttle_scope = 'contacts'
...
class UploadView(APIView):
throttle_scope = 'uploads'
...
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.ScopedRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'contacts': '1000/day',
'uploads': '20/day'
}
}
3.實(shí)例
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottle
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
throttle_classes = (UserRateThrottle,)
4.過(guò)濾的使用
有時(shí),在訪問(wèn)接口時(shí),需要的是符合一定條件的數(shù)據(jù)。此時(shí)可以通過(guò)過(guò)濾來(lái)實(shí)現(xiàn),Django Rest framework中,可以使用 django-fitlter 來(lái)實(shí)現(xiàn)過(guò)濾功能。在使用該功能前,需要提前安裝和注冊(cè) django-filter。
在終端輸入以下內(nèi)容完成 django-filter 的安裝:
pip install django-filter
在配置文件中配置以下內(nèi)容:
INSTALLED_APPS = [
...
'django_filters', # 注冊(cè)應(yīng)用
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
在視圖中添加 filter_fields 屬性,指定可以過(guò)濾的字段:
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
filter_fields = ('s_age')
此時(shí),可以通過(guò)訪問(wèn) http://127.0.0.1:8000/api/students/?s_age=11 來(lái)獲取所有年齡為 11 的學(xué)生信息。
5.小結(jié)
本小節(jié)為大家介紹了限流和過(guò)濾,通過(guò)限流可以限制用戶訪問(wèn)接口的頻率,起到防止用戶惡意訪問(wèn)的作用,過(guò)濾功能則是對(duì)數(shù)據(jù)的進(jìn)一步處理,篩選出符合用戶需求的數(shù)據(jù)或者按照用戶的需求,實(shí)現(xiàn)返回諸如按一定順序排列的數(shù)據(jù)等。