Django REST Framework API Guide 07
本節(jié)大綱
1、Permissions
2、Throttling
?
Permissions
權(quán)限是用來授權(quán)或者拒絕用戶訪問API的不同部分的不同的類的。基礎(chǔ)的權(quán)限劃分
1、IsAuthenticated 允許任何通過認(rèn)證的用戶訪問,拒絕任何沒有通過認(rèn)證的用戶。2、IsAuthenticatedOrReadOnly 認(rèn)證通過的用戶有所有訪問權(quán)限,反之只有只讀權(quán)限權(quán)限的定義
rest框架內(nèi)的權(quán)限總是被定義成一個(gè)權(quán)限類的列表。主視圖運(yùn)行前檢查,失敗就引發(fā)exceptions.PermissionDenied或者exceptions.NotAuthenticated異常
權(quán)限檢查失敗會(huì)根據(jù)下面的情況返回'403 Forbidden'或'401 Unauthorized':
1、請(qǐng)求驗(yàn)證成功,權(quán)限拒絕 # 返回HTTP 403 Forbidden響應(yīng) 2、請(qǐng)求沒有驗(yàn)證成功,最上面的驗(yàn)證類沒有使用'WWW-Authenticate'頭 # 返回'HTTP 403 Forbidden' 響應(yīng) 3、請(qǐng)求沒有認(rèn)證成功,最上面的認(rèn)證類沒有使用'WWW-Authenticate'頭 # 返回'HTTP 401 Unauthorized'響應(yīng),帶有一個(gè)合適的WWW-Authenticate頭?
對(duì)象級(jí)別的權(quán)限
在rest框架內(nèi),存在于一般視圖的.get_object()方法里,如果不允許,引發(fā)exceptions.PermissionDenied異常。
如果您正在編寫自己的視圖,并且希望強(qiáng)制執(zhí)行對(duì)象級(jí)別的權(quán)限,或者如果您在一般視圖上重寫.get_object()方法,那么您將需要在檢索對(duì)象時(shí)顯式地調(diào)用視圖上的.check_object_per.(request,obj)方法。失敗則引發(fā)PermissionDenied或者NotAuthenticated異常
def get_object(self):obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])self.check_object_permissions(self.request, obj)return obj對(duì)象級(jí)別權(quán)限的限制
事實(shí)上,因?yàn)樾试蛲ㄓ靡晥D不會(huì)自動(dòng)應(yīng)用對(duì)象級(jí)別的權(quán)限到每一個(gè)實(shí)例里。通常,當(dāng)使用對(duì)象級(jí)別權(quán)限時(shí),還希望適當(dāng)?shù)剡^濾queryset,以確保用戶只對(duì)它們?cè)试S查看的實(shí)例具有可見性。
?
設(shè)置權(quán)限策略
默認(rèn)可以全局設(shè)置,使用DEFAULT_PERMISSION_CLASSES
REST_FRAMEWORK = {'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',) }如果沒有指定,默認(rèn)設(shè)定是允許不受限制的訪問
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny', )在CBV的View或者ViewSet上
from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIViewclass ExampleView(APIView):permission_classes = (IsAuthenticated,)def get(self, request, format=None):content = {'status': 'request was permitted'}return Response(content)在FBV上
from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response@api_view(['GET']) @permission_classes((IsAuthenticated, )) def example_view(request, format=None):content = {'status': 'request was permitted'}return Response(content)?
API Reference
1、AllowAny
允許不受限制的訪問,無論請(qǐng)求有沒有被認(rèn)證。
2、IsAuthenticated
拒絕沒有通過認(rèn)證的用戶。適用于API只允許注冊(cè)用戶訪問
3、IsAdminUser
拒絕任何的用戶,除非user.is_staff為True才能訪問
4、IsAuthenticatedOrReadOnly
允許通過認(rèn)證的用戶執(zhí)行任何請(qǐng)求,沒有通過認(rèn)證的用戶是只讀權(quán)限,安全方法:GET,?HEAD?或者?OPTIONS.
?
DjangoModelPermissions
此權(quán)限綁定到Django標(biāo)準(zhǔn)的django.contrib.auth 模型權(quán)限。必須紙杯應(yīng)用于有.queryset屬性的視圖。只有被認(rèn)證并有相關(guān)模型權(quán)限的用戶才能被授權(quán)
POST # 對(duì)應(yīng)model的add權(quán)限 PUT和PATCH # 對(duì)應(yīng)model的change權(quán)限 delete # 對(duì)應(yīng)model的delete權(quán)限視圖不包含queryset屬性
如果view里面沒有queryset,而是重寫了get_queryset()方法,在這種案例里面,我們還建議用前哨查詢?cè)O(shè)置標(biāo)記視圖,這樣類能決定需要的權(quán)限。
queryset = User.objects.none() # Required for DjangoModelPermissionsDjangoModelPermissionOrAnonReadOnly
跟DjangoModelOermissions很像,沒有認(rèn)證的用戶只讀權(quán)限
DjangoObjectPermission
跟DjangoModelPermissions一樣
?
Custom Permission
實(shí)施客制化權(quán)限,重寫BasePermission,實(shí)行下面的方法中的一個(gè)或多個(gè)
.has_permission(self, request, view) .has_object_permission(self, request, view, obj)這些方法在應(yīng)該授權(quán)時(shí)返回True。你需要測(cè)試請(qǐng)求是讀操作或?qū)懖僮?#xff0c;應(yīng)該檢查請(qǐng)求方法是否在'GET', 'OPTIONS'和'HEAD' 組成的SAFE_METHODS里面
if request.method in permissions.SAFE_METHODS:# Check permissions for read-only request else:# Check permissions for write requesthas_object_permission方法只有在通過視圖級(jí)別的has_permission方法時(shí)才會(huì)被調(diào)用。另外為了讓實(shí)例級(jí)別的檢查運(yùn)行,視圖代碼應(yīng)該顯式的調(diào)用.check_object_permissions(request, obj). 如果你使用通用視圖,默認(rèn)將自動(dòng)處理。
檢查失敗會(huì)引發(fā)PermissionDenied異常。改變錯(cuò)誤信息跟異常綁定,在你的客制化權(quán)限里面申明message。否則PermissionDenied的default_detail屬性將被使用
from rest_framework import permissionsclass CustomerAccessPermission(permissions.BasePermission):message = 'Adding customers not allowed.'def has_permission(self, request, view):...示例
from rest_framework import permissionsclass BlacklistPermission(permissions.BasePermission):"""Global permission check for blacklisted IPs."""def has_permission(self, request, view):ip_addr = request.META['REMOTE_ADDR']blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()return not blacklisted跟全局設(shè)置很像,你可以創(chuàng)建一個(gè)對(duì)象級(jí)別的權(quán)限對(duì)所有到來的請(qǐng)求,只有通過的能操作一個(gè)特殊的對(duì)象實(shí)例。
class IsOwnerOrReadOnly(permissions.BasePermission):"""Object-level permission to only allow owners of an object to edit it.Assumes the model instance has an `owner` attribute."""def has_object_permission(self, request, view, obj):# Read permissions are allowed to any request,# so we'll always allow GET, HEAD or OPTIONS requests.if request.method in permissions.SAFE_METHODS:return True# Instance must have an attribute named `owner`.return obj.owner == request.userThrottling
節(jié)流(throttling)在rest框架內(nèi)總是被定義成一組類的列表。同樣在主題視圖之前執(zhí)行檢查,失敗引發(fā)exceptions.Throttled異常
設(shè)置節(jié)流策略
全局設(shè)置使用DEFAULT_THROTTLE_CLASSES和DEFAULT_THROTTLE_RATES參數(shù)。
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.AnonRateThrottle','rest_framework.throttling.UserRateThrottle'),'DEFAULT_THROTTLE_RATES': {'anon': '100/day','user': '1000/day'} }DEFAULT_THROTTLE_RATES可以包含second, minute, hour或day作為節(jié)流周期。
你也可以為每個(gè)視圖或者視圖集設(shè)置節(jié)流,CBV格式
from rest_framework.response import Response from rest_framework.throttling import UserRateThrottle from rest_framework.views import APIViewclass ExampleView(APIView):throttle_classes = (UserRateThrottle,)def get(self, request, format=None):content = {'status': 'request was permitted'}return Response(content)在FBV里面
@api_view(['GET']) @throttle_classes([UserRateThrottle]) def example_view(request, format=None):content = {'status': 'request was permitted'}return Response(content)?
設(shè)置緩存
節(jié)流類是REST框架提供的,使用了Django的緩存后端。你應(yīng)該確保已經(jīng)設(shè)置了合適的緩存設(shè)定。
如果你想使用一個(gè)緩存而不是默認(rèn)的'default',你可以創(chuàng)建客制化的節(jié)流類并設(shè)置緩存cache屬性
class CustomAnonRateThrottle(AnonRateThrottle):cache = get_cache('alternate')別忘了設(shè)置DEFAULT_THROTTLE_CLASSES或者使用throttle_classes視圖屬性
API Reference
AnonRateThrottle
AnonRateThrottle只限制沒有認(rèn)證的用戶。訪問請(qǐng)求的IP地址被用來生成唯一的鍵用來做限制。從下面幾個(gè)方面來做請(qǐng)求率限制
1、類上的rate屬性重寫AnonRateThrottle并設(shè)置此屬性 2、DEFAULT_THROTTLE_RATES['anon']設(shè)置AnonRateThrottle很適合做對(duì)于未知資源請(qǐng)求的限制
?
UserRateThrottle
UserRateThrottle將通過一個(gè)給定的API速率來限制用戶在API上的請(qǐng)求。用戶的ID被用來生成唯一的節(jié)流鍵。未認(rèn)證的請(qǐng)求將使用IP地址來生成唯一節(jié)流鍵。
請(qǐng)求的限定方面
1、rate屬性,重寫的UserRateThrottle,設(shè)置此屬性 2、DEFAULT_THROTTLE_RATES['user']設(shè)置一個(gè)API可能同時(shí)有多個(gè)UserRateThrottle在同一個(gè)地方。所以你需要重寫UserRateThrottle并設(shè)置唯一'scope'為每一個(gè)類
class BurstRateThrottle(UserRateThrottle):scope = 'burst'class SustainedRateThrottle(UserRateThrottle):scope = 'sustained' REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ('example.throttles.BurstRateThrottle','example.throttles.SustainedRateThrottle'),'DEFAULT_THROTTLE_RATES': {'burst': '60/min','sustained': '1000/day'} }UserRateThrottle適用于如果想簡(jiǎn)單全局限制每位用戶的速率。
ScopedRateThrottle
ScopedRateThrottle類被用來限制訪問API的特殊部分。只有被訪問的視圖包含.throttle_scope屬性時(shí)節(jié)流才被應(yīng)用。然后,通過將請(qǐng)求的“scope”與唯一的用戶ID或IP地址串聯(lián),形成唯一的節(jié)流鍵。被允許的請(qǐng)求速率被設(shè)置里面的DEFAULT_THROTTLE_RATES決定,通過使用鍵值scope
class ContactListView(APIView):throttle_scope = 'contacts'...class ContactDetailView(APIView):throttle_scope = 'contacts'...class UploadView(APIView):throttle_scope = 'uploads'...然后設(shè)置全局
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.ScopedRateThrottle',),'DEFAULT_THROTTLE_RATES': {'contacts': '1000/day', # 1000requests per day'uploads': '20/day' # 20request per day} }自定義 throttles
創(chuàng)建一個(gè)自定義節(jié)流,重寫B(tài)aseThrottle執(zhí)行.allow_request(self, request, view). 這個(gè)方法應(yīng)該返回True如果請(qǐng)求應(yīng)該被允許,否則False。同時(shí)你也需要重寫.wait()方法,如果執(zhí)行,.wait()方法講返回一個(gè)推薦的的秒數(shù)在視圖下一次請(qǐng)求之前。.wait()方法只有在.allow_request()返回false的時(shí)候?qū)⒈徽{(diào)用
import randomclass RandomRateThrottle(throttling.BaseThrottle):def allow_request(self, request, view):return random.randint(1, 10) != 1?
轉(zhuǎn)載于:https://www.cnblogs.com/wuzdandz/p/9665645.html
總結(jié)
以上是生活随笔為你收集整理的Django REST Framework API Guide 07的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Taro项目遇到的问题
- 下一篇: 1.需要对txt存放的测试数据做去重处理