zoukankan      html  css  js  c++  java
  • Django Rest Framework --- 频率组件

    一、频率组件的作用

      在我们平常浏览网站的时候会发现,一个功能你点击很多次后,系统会让你休息会在点击,这其实就是频率控制,主要作用是限制你在一定时间内提交请求的次数,减少服务器的压力。

    modles.py

    二、自定义频率组件类

    #(1)取出访问者ip
    # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
    # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
    # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
    # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
    自定义频率组件的逻辑
    • myauth.py
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.permissions import BasePermission
    from app01.models import TokenUser
    from rest_framework.exceptions import AuthenticationFailed
    from rest_framework.throttling import BaseThrottle
    
    class MyAuthentication(BaseAuthentication):
        #验证过程
        def authenticate(self, request):
            token = request.GET.get('token')
            token_user = TokenUser.objects.filter(token=token).first()
            if token_user:
                return token_user.user,token
            else:
                raise AuthenticationFailed('你还未登录,请先登录')
    
    
    class MyPermission(BasePermission):
        message = '该用户的权限无法使用该功能'
        def has_permission(self, request, view):
            type = int(request.user.type)
            if type == 2 or type ==3:
                return True
            else:
                return False
    
    
    import time
    class MyThrottle():
        # (1)取出访问者ip
        # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
        # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        visit_dic = {}  # 访问的ip时间字典
        def __init__(self):
            self.history = None   #某个ip的时间列表
        def allow_request(self, request, view):
            ip = request.META.get('REMOTE_ADDR')  #获取请求中的ip地址
            now_time = time.time()
            print(self.visit_dic)
            if ip not in self.visit_dic:
                self.visit_dic[ip] = [now_time,]  #ip第一次来时,添加ip和时间至ip时间字典
                return True
            self.history = self.visit_dic.get(ip,None)
            while self.history and (now_time-self.history[-1]>60):
                self.history.pop()
            if len(self.history)<3:
                self.history.insert(0,now_time)
                return True
            else:
                return False
        def wait(self):
            pass
    • views.py
    from django.shortcuts import render
    from rest_framework.response import Response
    
    # Create your views here.
    from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView
    from app01 import models
    from app01.myserializer import BookSerializer
    from rest_framework.views import APIView
    from app01.myAuth import MyAuthentication,MyPermission,MyThrottle
    
    class BooksView(ListCreateAPIView):
        authentication_classes = [MyAuthentication]  #加上验证的类,如果有多个,会从做到右依次验证
        permission_classes = [MyPermission]
        throttle_classes = [MyThrottle]
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer
    
    
    class BookView(RetrieveUpdateDestroyAPIView):
        authentication_classes = [MyAuthentication]
        queryset = models.Book.objects.all()
        serializer_class = BookSerializer
    
    
    import uuid
    #登录
    class Login(APIView):
        def post(self,request):
            name = request.data.get('name')
            pwd = request.data.get('pwd')
            user = models.User.objects.filter(name=name,pwd=pwd).first()
            if user:
                token = uuid.uuid4()
                models.TokenUser.objects.update_or_create(user=user,defaults={"token":token})
                response = {"status":100,"message":"登录成功"}
            else:
                response = {"status": 200, "message": "登录失败"}
            return Response(response)

    其余与权限认证代码一致。

    结果1:

    结果2:

    三、继承SimpleRateThrottle的频率组件

    • myauth.py
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.permissions import BasePermission
    from app01.models import TokenUser
    from rest_framework.exceptions import AuthenticationFailed
    from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
    
    class MyAuthentication(BaseAuthentication):
        #验证过程
        def authenticate(self, request):
            token = request.GET.get('token')
            token_user = TokenUser.objects.filter(token=token).first()
            if token_user:
                return token_user.user,token
            else:
                raise AuthenticationFailed('你还未登录,请先登录')
    
    
    class MyPermission(BasePermission):
        message = '该用户的权限无法使用该功能'
        def has_permission(self, request, view):
            type = int(request.user.type)
            if type == 2 or type ==3:
                return True
            else:
                return False
    
    class MyThrottle(SimpleRateThrottle):
        scope = 'throttle'  #settins中的配置
        def get_cache_key(self, request, view):
            return request.META.get('REMOTE_ADDR',None)

    四、频率组件的使用方式

    1.局部使用:在需要使用权限验证的视图类中写上变量 throttle_classes= [ 权限类名,]

    2.全局使用:在settings.py配置文件中,加入 REST_FRAMEWORK = {‘DEFAULT_THROTTLE_CLASSES’:'权限类的具体位置例如(app01.myauth.MyThrottle)'}

    3.全局使用,局部禁用:在全局使用的基础上,在不需要验证权限的视图类中,将变量 throttle_classes改为 [ ]  即 throttle_classes  =  [ ]

    五、频率组件的源码分析

  • 相关阅读:
    Mysql查询一段时间记录
    exosip2 的简单使用
    oSIP协议栈浅析
    Oracle 11g New 与分区和存储相关的增强功能
    手动配置S2SH三大框架报错(四)
    手动配置S2SH三大框架报错(三)
    手动配置S2SH三大框架报错(二)
    手动配置S2SH三大框架报错(一)
    链表基本操作的实现
    SVN上传项目报错
  • 原文地址:https://www.cnblogs.com/846617819qq/p/10617657.html
Copyright © 2011-2022 走看看