rest framework 認證 權限 頻率

 認證組件

發生位置

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

  使用內置 SimpleRateThrottle 頻率控制組件

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次最多 } }
相關文章
相關標籤/搜索