zoukankan      html  css  js  c++  java
  • restframework认证权限频率

    认证组件

    认证组件的流程

    --> CBV里的APIView --> self.dispatch() --> self.initial() 
    --> self.perform_authentication() --> request.user
    --> self.initialize_request     --> Request类
    --> def user(self) 
    --> self._authenticate()    
            for authenticator in self.authenticators:
                try:
                    user_auth_tuple = authenticator.authenticate(self)
                except exceptions.APIException:
                    self._not_authenticated()
                    raise
    
                if user_auth_tuple is not None:
                    self._authenticator = authenticator
                    self.user, self.auth = user_auth_tuple
                    return
    
            self._not_authenticated()
    认证流程

    app01.utils.py下

    class TokenAuth(BaseAuthentication):
        """自己写的认证类"""
    
        def authenticate(self, request):
            token = request.GET.get("token")
            token_obj = Token.objects.filter(token=token).first()
            if not token_obj:
                # 认证失败
                raise exceptions.AuthenticationFailed("认证失败!")
            else:
                # print("token_obj.user.name", token_obj.user.name)
                # print("token_obj.token", token_obj.token)
                return token_obj.user.name, token_obj.token

    局部的配置

    views.py下

    from app01.utils import * 
    class PublishView(APIView):
        # 认证组件
        authentication_classes = [TokenAuth, ]
    
        def get(self, request):
    
            print("token_obj.user.name", request.user)  # 在认证组件注册进去的
            print("token_obj.token", request.auth)
            publish_list = Publish.objects.all()
            ps = PublisherModerSerializers(publish_list, many=True)
            return Response(ps.data)
    
        def post(self, request):
            ps = PublisherModerSerializers(data=request.data)
            if ps.is_valid():
                ps.save()
                return Response(ps.data)
            else:
                return Response(ps.errors)

    全局的配置

    setting.py下

    setting.py
        REST_FRAMEWORK = {
            "DEFAULT_AUTHENTICATION_CLASSES": ("app01.utils.TokenAuth", ),
    
        }

    # 某条接口不想走全局的认证的话,可以在局部配一条空的认证配置
    authentication_classes = []

    权限组件

    权限组件

    app01.utils.py下

    class SVIPPermission(object):
        """权限类"""
        message = "只有超级用户可以访问"
    
        def has_permission(self, request, view):
            username = request.user
            user_type = User.objects.filter(name=username).first().user_type
            if user_type == 3:
                # 通过验证
                return True
            else:
                # 验证失败
                return False

    局部的配置

    views.py下

    from app01.utils import *
    
    class BookViewSet(generics.ListCreateAPIView):
        permission_classes = [SVIPPermission,]
        queryset = Book.objects.all()
        serializer_class = BookSerializers

    全局的配置

    setting.py下

    REST_FRAMEWORK={
        "DEFAULT_PERMISSION_CLASSES":["app01.utils.SVIPPermission",]
    }

    频率组件

    app01.utils.py下

    from rest_framework.throttling import BaseThrottle
    
    VISIT_RECORD={}
    
    class VisitThrottleBetter(BaseThrottle):
    """优化过代码的频率限制类"""

    def __init__(self):
    self.visited_record = None

    def allow_request(self, request, view):
    """在allow_request中编写频率业务逻辑"""
    remote_addr = request.META.get('REMOTE_ADDR')
    # print(remote_addr)
    ctime = time.time()

    # 1 有记录来则将其添加到访问记录里
    VISIT_RECORD.setdefault(remote_addr, []).insert(0, ctime)

    # 2 判断列表的最后一个是否小于(当前时间-频率时间);如果小于,则剔除;
    self.visited_record = VISIT_RECORD.get(remote_addr)
    while self.visited_record and self.visited_record[-1] < ctime - 60:
    self.visited_record.pop()

    # 3 然后再判断列表的长度是否超过频率数,如不超过,则return true,else false
    if len(self.visited_record) <= 3:
    # /不超过频率数
    return True
    else:
    # /超过频率数
    return False

    def wait(self):
    """如果allow_request中没有通过, wait里写再等多少秒就可以访问了"""
    ctime = time.time()
    first_visit_duration = ctime - self.visited_record[-1] # 现在离第一次访问过了多久啦
    return 60 - first_visit_duration

    views.py下

    from app01.utils import *
    
    class BookViewSet(generics.ListCreateAPIView):
        throttle_classes = [VisitThrottle,]
        queryset = Book.objects.all()
        serializer_class = BookSerializers

    setting.py下

    REST_FRAMEWORK={
        "DEFAULT_THROTTLE_CLASSES":["app01.utils.VisitThrottle",]
    }

    内置throttle类

    app01.utils.py下

    class VisitThrottle(SimpleRateThrottle):
    
        scope="visit_rate"
        def get_cache_key(self, request, view):
    
            return self.get_ident(request)

    setting.py下

    REST_FRAMEWORK={
        "DEFAULT_THROTTLE_CLASSES":["app01.utils.VisitThrottle",],
        "DEFAULT_THROTTLE_RATES":{
        "visit_rate":"5/m",
    }
    }
  • 相关阅读:
    炒炒饼分锅喂
    奥运会
    360和腾讯QQ共存
    Lenovo F41 使用WinXP不能全屏看Flash格式的电影的解决方法
    如何在Windows server 2003上安装和设置Citrix MetaFrame XP FR3
    “电脑人才”是怎么炼成的
    Lenovo F41 使用WinXP不能全屏看Flash格式的电影的解决方法
    学车
    终于有了自己的本本了
    学车
  • 原文地址:https://www.cnblogs.com/sunch/p/9994065.html
Copyright © 2011-2022 走看看