• 认证组件、权限组件、频率组件、


    今天讲认证组件,权限组件、频率组件、

    我们先写一个登陆,之前用户在登陆的时候都会带上cokie,session,他会带上用户的信息去访问请求,不用用户每次都输入用户名和密码。

     用户在登陆的时候,向用户随机分配一个字符串,用户再次登陆的时候会带着这个字符串进行认证。

     先在model里面添加两个表,user表和usertoken表,

    class User(models.Model):
        user = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        type = ((1,'VIP'),(2,'SVIP'),(3,'SSVIP'))
        user_type = models.IntegerField(choices=type)
    class UserToken(models.Model):
        user = models.OneToOneField(to='User')
        token = models.CharField(max_length=128)

    login视图函数:

    然后就是写认证组件了,

    之前我们看过解析器的要在视图类函数中加上  parser_classes = [JSONParser,FormParser,MultiPartParser]  这样一个变量,如果不写这个变量,会去默认的这个变量

    同样我们把   authentication_classes = [UserAuth]  这个变量加在  book表的视图类函数中。

    我们再把源码走一遍:

    APIView中的dispatch方法会重新封装request,

    点击去initial:

     见到request.user应该想到的是user是一个静态方法。

     从重新封装的那个request中找user方法。

     点进去之后,

     

    我们可以看一下默认的authenticate方法中是不是返回两个值。这样认证组件的源码就算执行完了。

     如果我们不定义 authentication_classes = [UserAuth]  他会从试图类中找 authentication_classes,如果找不到,就去全局的settings中找,再找不到就去默认的settings中找,具体解析看前面的解析器部分。

     来看代码:

    from app01.models import UserToken
    from rest_framework.exceptions import AuthenticationFailed
    
    class UserAuth(object):
        def authenticate_header(self,request):
            pass
        def authenticate(self,request):
            token = request.GET.get('token')
            usertoken = UserToken.objects.filter(token=token).first()
            if usertoken:
                return usertoken.user,usertoken.token
            else:
                raise AuthenticationFailed('认证失败')   #  抛出异常错误

     当然,我们定义的 authentication_classes = [UserAuth,UserAuth2]  也可以放多个认证类,如果第一个认证类返回空,就走第二个认证类,知道有返回值。

    最后的认证类代码:

    权限组件

    同样我们把  permission_classes = [SVIPPermission]  权限变量添加到book表的视图类中,

    同样的道理:

     来看代码:

    class SVIPPermission(object):
        message = '您没有访问权限!!!'
        def has_permission(self,request,view):
            if request.user.user_type >= 2:
                return True
            return False

    3.频率组件

    同样的道理,

     

    我们来写一个每分钟限制访问三次的限制频率。

    我们每次访问频率受限制的时候,会提示多少时间后才能继续访问,

    from rest_framework.throttling import BaseThrottle
    VISIT_CODE = {}
    class VisitThrottle(BaseThrottle):
        def __init__(self):
            self.history = None
        def allow_request(self,request,view):
            # 拿到用户请求的ip值
            remote_addr = request.META.get('REMOTE_ADDR')
            import time
            ctime = time.time()
            # 如果IP值不再VISIT_CODE中,说明用户之前没有访问过,
            if remote_addr not in VISIT_CODE:
                VISIT_CODE[remote_addr] = [ctime,] # {‘127.0.0.1’:[11:10:10,]}
            history = VISIT_CODE[remote_addr]
            self.history = history
            # 如果history最后一个和当前时间差值大于60s,就把他删除掉。
            while history and ctime - history[-1] > 60:
                history.pop()
            if len(history) > 3:
                return False
            else:
                history.insert(0,ctime)
                return True
        def wait(self):
            import time
            ctime = time.time()
            # 60 - (当前时间与第一次访问的差值)
            return 60-(ctime-self.history[-1])

    这是我们自己写的每分钟访问三次,这样就写死了。其实rest_framework也帮我们做了这样的频率限制。

     需要在全局的settings中配置:

    10/d,每天访问10此

    10/w,每周访问10次

  • 相关阅读:
    用JSP实现的商城购物车模块
    C语言中的static 具体分析
    JAVA动态代理
    ACM之跳骚---ShinePans
    thinkphp5项目--个人博客(二)
    mysql数据类型
    htm、html、shtml网页区别
    thinkphp命名空间
    github README.md教程
    如何在github的README.md中添加图片
  • 原文地址:https://www.cnblogs.com/yb635238477/p/9683563.html
Copyright © 2020-2023  润新知