APIview 類種的 dispatch 方法執行到 initial 方法 進行 認證組件認證python
rest_framework.authentication
# 用戶用戶自定義的重寫繼承類 class BaseAuthentication(object): ... # 自定義重寫的認證方法 def authenticate(self, request):... # 如下4種爲自帶 認證 # 基於用戶名和密碼的認證 class BasicAuthentication(BaseAuthentication):... # 基於 session 的認證 class SessionAuthentication(BaseAuthentication):... # 基於 token 的認證 class TokenAuthentication(BaseAuthentication):... # 基於遠端服務的認證 class RemoteUserAuthentication(BaseAuthentication):...
from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from api.models import * class YTAuth(BaseAuthentication): def authenticate(self, request): token = request.query_params.get('token') obj = UserAuthToken.objects.filter(token=token).first() if not obj: return AuthenticationFailed({'code': 1001, 'erroe': '認證失敗'}) return (obj.user.username, obj) # 返回的必須是元組 而後元組的裏面含有兩個值 而且對應的取值是rquest.user(user對象),和reques.auth(token對象)
class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer authentication_classes = [YTAuth, ]
# 在settings.py中配置 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.YTAuth", ] }
APIview 類種的 dispatch 方法執行到 initial 方法 進行 認證組件執行後,進行權限組件認證api
rest_framework.permissions
# 自定義重寫的類 class BasePermission(object): ... # 自定義重寫的方法 def has_permission(self, request, view): ... # AllowAny 容許全部用戶 class AllowAny(BasePermission):... # IsAuthenticated 僅經過認證的用戶 class IsAuthenticated(BasePermission):... # IsAdminUser 僅管理員用戶 class IsAdminUser(BasePermission):... # IsAuthenticatedOrReadOnly 認證的用戶能夠徹底操做,不然只能get讀取 class IsAuthenticatedOrReadOnly(BasePermission):...
from rest_framework.permissions import BasePermission class MyPermission(BasePermission): message = 'VIP用戶才能訪問' def has_permission(self, request, view): # 認證判斷已經提供了request.user if request.user and request.user.type == 2: return True else: return False
class CommentViewSet(ModelViewSet):
queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer authentication_classes = [YTAuth, ] permission_classes = [YTPermission, ]
# 在settings.py中設置rest framework相關配置項
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.YTAuth", ],
"DEFAULT_PERMISSION_CLASSES": ["app01.utils.YTPermission", ]
}
APIview 類種的 dispatch 方法執行到 initial 方法 進行 認證組件執行,權限組件認證後 ,進行頻率組件的認證session
rest_framework.throttling
# 須要自定義重寫的類 class BaseThrottle(object): ... # 自定義頻率的邏輯實現方法 def allow_request(self, request, view): ... # 自定義 限制後邏輯實現方法 def wait(self): ... # 內置的頻率控制組件 經常使用的是這個 class SimpleRateThrottle(BaseThrottle): ... # 其餘都不怎麼用 class AnonRateThrottle(SimpleRateThrottle): ... # 其餘都不怎麼用 class UserRateThrottle(SimpleRateThrottle): # 其餘都不怎麼用 class ScopedRateThrottle(SimpleRateThrottle):
import time VISIT_RECORD = {} class YTThrottle(object): # 直接繼承 object 就能夠了 def __init__(self): self.history = None def allow_request(self, request, view): """ 自定義頻率限制60秒內只能訪問三次 """ # 獲取用戶IP ip = request.META.get("REMOTE_ADDR") timestamp = time.time() if ip not in VISIT_RECORD: VISIT_RECORD[ip] = [timestamp, ] return True history = VISIT_RECORD[ip] self.history = history history.insert(0, timestamp) while history and history[-1] < timestamp - 60: history.pop() if len(history) > 3: return False else: return True def wait(self): """ 限制時間還剩多少 """ timestamp = time.time() return 60 - (timestamp - self.history[-1])
class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer throttle_classes = [YTThrottle, ]
# 在settings.py中設置rest framework相關配置項 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.YTAuth", ], "DEFAULT_PERMISSION_CLASSES": ["app01.utils.YTPermission", ] "DEFAULT_THROTTLE_CLASSES": ["app01.utils.YTThrottle", ] }
ps:app
from rest_framework.throttling import SimpleRateThrottle class VisitThrottle(SimpleRateThrottle): scope = "xxx" def get_cache_key(self, request, view): return self.get_ident(request)
# 在settings.py中設置rest framework相關配置項 REST_FRAMEWORK = { ...
"DEFAULT_THROTTLE_RATES": { "xxx": "5/m", # 每分鐘5次最多 } }