zoukankan      html  css  js  c++  java
  • 04,认证、权限、频率

    认证组件

    Django原生的authentic组件为我们的用户注册与登录提供了认证功能,十分的简介与强大。同样DRF也为我们提供了认证组件,一起来看看DRF里面的认证组件是怎么为我们工作的!
     
    models.py

     
     
     
    15
     
     
     
     
     
    1
    # 定义一个用户表和一个保存用户Token的表
    2
    
    
    3
    
    
    4
    class UserInfo(models.Model):
    5
        username = models.CharField(max_length=16)
    6
        password = models.CharField(max_length=32)
    7
        type = models.SmallIntegerField(
    8
            choices=((1, '普通用户'), (2, 'VIP用户')),
    9
            default=1
    10
        )
    11
    
    
    12
    
    
    13
    class Token(models.Model):
    14
        user = models.OneToOneField(to='UserInfo')
    15
        token_code = models.CharField(max_length=128)
     
     
     
    url

     
     
     
    1
     
     
     
     
     
    1
        path('login/', views.LoginView.as_view()),
     
     
     
    views.py

     
     
     
    38
     
     
     
     
     
    1
    # 视图主要处理用户名、密码是否正确,用户每一次请求都要带着专有token来!
    2
    import hashlib, time
    3
    from rest_framework.response import Response
    4
    from rest_framework.views import APIView
    5
    
    
    6
    
    
    7
    def get_random_token(username):
    8
        """
    9
        根据用户名和时间戳生成随机token
    10
        :param username:
    11
        :return:
    12
        """
    13
        timestamp = str(time.time())
    14
        m = hashlib.md5(bytes(username, encoding="utf8"))
    15
        m.update(bytes(timestamp, encoding="utf8"))
    16
        return m.hexdigest()
    17
    
    
    18
    
    
    19
    class LoginView(APIView):
    20
        """
    21
        校验用户名密码是否正确从而生成token的视图
    22
        """
    23
        def post(self, request):
    24
            res = {"code": 0}
    25
            print(request.data)
    26
            username = request.data.get("username")
    27
            password = request.data.get("password")
    28
    
    
    29
            user = models.UserInfo.objects.filter(username=username, password=password).first()
    30
            if user:
    31
                # 如果用户名密码正确
    32
                token = get_random_token(username)
    33
                models.Token.objects.update_or_create(defaults={"token_code": token}, user=user)
    34
                res["token"] = token
    35
            else:
    36
                res["code"] = 1
    37
                res["error"] = "用户名或密码错误"
    38
            return Response(res)
     
     
     
    定义认证类model_serializer.py

     
     
     
    18
     
     
     
     
     
    1
    # 这一步是要对着源码才能写出来
    2
    from rest_framework.authentication import BaseAuthentication
    3
    from rest_framework.exceptions import AuthenticationFailed
    4
    
    
    5
    
    
    6
    class MyAuth(BaseAuthentication):
    7
        def authenticate(self, request):
    8
            if request.method in ["POST", "PUT", "DELETE"]:
    9
                request_token = request.data.get("token", None)
    10
                if not request_token:
    11
                    raise AuthenticationFailed('缺少token')
    12
                token_obj = models.Token.objects.filter(token_code=request_token).first()
    13
                if not token_obj:
    14
                    raise AuthenticationFailed('无效的token')
    15
                return token_obj.user.username, None
    16
            else:
    17
                return None, None
    18
    
    
     
     
     
    全局配置

     
     
     
    4
     
     
     
     
     
    1
    # 在settings.py中配置
    2
    REST_FRAMEWORK = {
    3
        "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ]
    4
    }
     
     
     

    权限组件

    只有vip才能看的内容
     
    自定义权限类

     
     
     
    15
     
     
     
     
     
    1
    # 自定义权限类
    2
    from rest_framework.permissions import BasePermission
    3
    
    
    4
    class MyPermission(BasePermission):
    5
        message = 'VIP用户才能访问'
    6
    
    
    7
        def has_permission(self, request, view):
    8
            """
    9
            自定义权限只有VIP用户才能访问
    10
            """
    11
            # 因为在进行权限判断之前已经做了认证判断,所以这里可以直接拿到request.user
    12
            if request.user and request.user.type == 2:  # 如果是VIP用户
    13
                return True
    14
            else:
    15
                return False
     
     
     
    视图级别配置

     
     
     
    6
     
     
     
     
     
    1
    class CommentViewSet(ModelViewSet):
    2
    
    
    3
        queryset = models.Comment.objects.all()
    4
        serializer_class = app01_serializers.CommentSerializer
    5
        authentication_classes = [MyAuth, ]
    6
        permission_classes = [MyPermission, ]
     
     
     
    全局配置

     
     
     
    4
     
     
     
     
     
    1
    REST_FRAMEWORK = {
    2
        "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
    3
        "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
    4
    }
     
     
     

    频率组件

    频率:限制用户访问网站的频率
    自定义限制类

     
     
     
    33
     
     
     
     
     
    1
    VISIT_RECORD = {}
    2
    # 自定义限制
    3
    class MyThrottle(object):
    4
    
    
    5
        def __init__(self):
    6
            self.history = None
    7
    
    
    8
        def allow_request(self, request, view):
    9
            """
    10
            自定义频率限制60秒内只能访问三次
    11
            """
    12
            # 获取用户IP
    13
            ip = request.META.get("REMOTE_ADDR")
    14
            timestamp = time.time()
    15
            if ip not in VISIT_RECORD:
    16
                VISIT_RECORD[ip] = [timestamp, ]
    17
                return True
    18
            history = VISIT_RECORD[ip]
    19
            self.history = history
    20
            history.insert(0, timestamp)
    21
            while history and history[-1] < timestamp - 60:
    22
                history.pop()
    23
            if len(history) > 3:
    24
                return False
    25
            else:
    26
                return True
    27
    
    
    28
        def wait(self):
    29
            """
    30
            限制时间还剩多少
    31
            """
    32
            timestamp = time.time()
    33
            return 60 - (timestamp - self.history[-1])
     
     
     
    视图级别配置

     
     
     
    x
     
     
     
     
     
    1
    class CommentViewSet(ModelViewSet):
    2
    
    
    3
        queryset = models.Comment.objects.all()
    4
        serializer_class = app01_serializers.CommentSerializer
    5
        throttle_classes = [MyThrottle, ]
     
     
     
    全局配置

     
     
     
     
     
     
     
     
     
    1
    # 在settings.py中设置rest framework相关配置项
    2
    REST_FRAMEWORK = {
    3
        "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
    4
        "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
    5
        "DEFAULT_THROTTLE_CLASSES": ["app01.utils.MyThrottle", ]
    6
    }
     
     
     

    认证组件的源码阅读

    新构建的request里面的源码的user方法

     

    源码走到了这里其实就已经需要我们自己来进行认证了。就可以对前端的请求进行认证,到底该怎么认证,还得继续往下走!

     

    权限组件的源码阅读

     

    相比较与认证组件,权限组件就更加的简洁了

    频率组件的注意部分

  • 相关阅读:
    IDEA插件备忘录
    SpringBoot2基础笔记
    EasyCode模板,配合通用mapper,dubbo项目使用
    七牛云存储
    Apache POI
    SSM项目中关于配置的一二三
    SSM整合笔记
    Spring5学习笔记
    ThinkPHP框架,按分类,计算商品价格区间,来完成价格搜索
    PHP常用符号和函数
  • 原文地址:https://www.cnblogs.com/pontoon/p/10217414.html
Copyright © 2011-2022 走看看