zoukankan      html  css  js  c++  java
  • Django

    目录

    • 认证
    • 权限
    • 限制

    1,认证

    1.1 表

    • 定义一个用户表和一个保存用户Token的表:
    class UserInfo(models.Model):
        username = models.CharField(max_length=16)
        password = models.CharField(max_length=32)
        type = models.SmallIntegerField(
            choices=((1, '普通用户'), (2, 'VIP用户')),
            default=1
        )
    
    
    class Token(models.Model):
        user = models.OneToOneField(to='UserInfo')
        token_code = models.CharField(max_length=128)
    

    1.2 定义一个登录视图:

    def get_random_token(username):
        """
        根据用户名和时间戳生成随机token
        :param username:
        :return:
        """
        import hashlib, time
        timestamp = str(time.time())
        m = hashlib.md5(bytes(username, encoding="utf8"))
        m.update(bytes(timestamp, encoding="utf8"))
        return m.hexdigest()
    
    
    class LoginView(APIView):
        """
        校验用户名密码是否正确从而生成token的视图
        """
        def post(self, request):
            res = {"code": 0}
            print(request.data)
            username = request.data.get("username")
            password = request.data.get("password")
    
            user = models.UserInfo.objects.filter(username=username, password=password).first()
            if user:
                # 如果用户名密码正确
                token = get_random_token(username)
                models.Token.objects.update_or_create(defaults={"token_code": token}, user=user)
                res["token"] = token
            else:
                res["code"] = 1
                res["error"] = "用户名或密码错误"
            return Response(res)
    

    1.3 定义一个认证类

    from rest_framework.authentication import BaseAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    
    
    class MyAuth(BaseAuthentication):
        def authenticate(self, request):
            if request.method in ["POST", "PUT", "DELETE"]:
                request_token = request.data.get("token", None)
                if not request_token:
                    raise AuthenticationFailed('缺少token')
                token_obj = models.Token.objects.filter(token_code=request_token).first()
                if not token_obj:
                    raise AuthenticationFailed('无效的token')
                return token_obj.user.username, None
            else:
                return None, None
    

    1.4 视图级别认证

    class CommentViewSet(ModelViewSet):
    
        queryset = models.Comment.objects.all()
        serializer_class = app01_serializers.CommentSerializer
        authentication_classes = [MyAuth, ]
    

    1.5 全局级别认证

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

    2,权限

    2.1 自定义一个权限类

    # 自定义权限
    class MyPermission(BasePermission):
        message = 'VIP用户才能访问'
    
        def has_permission(self, request, view):
            """
            自定义权限只有VIP用户才能访问
            """
            # 因为在进行权限判断之前已经做了认证判断,所以这里可以直接拿到request.user
            if request.user and request.user.type == 2:  # 如果是VIP用户
                return True
            else:
                return False
    

    2.2 视图级别配置

    class CommentViewSet(ModelViewSet):
    
        queryset = models.Comment.objects.all()
        serializer_class = app01_serializers.CommentSerializer
        authentication_classes = [MyAuth, ]
        permission_classes = [MyPermission, ]
    

    2.3 全局级别设置

    # 在settings.py中设置rest framework相关配置项
    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
        "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
    }
    

    3,限制

    3.1 自定义限制类

    VISIT_RECORD = {}
    # 自定义限制
    class MyThrottle(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])
    

    3.2 视图使用

    class CommentViewSet(ModelViewSet):
    
        queryset = models.Comment.objects.all()
        serializer_class = app01_serializers.CommentSerializer
        throttle_classes = [MyThrottle, ]
    

    3.3 全局使用

    在settings.py中设置rest framework相关配置项

    REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
    "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
    "DEFAULT_THROTTLE_CLASSES": ["app01.utils.MyThrottle", ]
    }

    
    ### 3.4 使用内置限制类
    

    from rest_framework.throttling import SimpleRateThrottle

    class VisitThrottle(SimpleRateThrottle):

    scope = "xxx"
    
    def get_cache_key(self, request, view):
        return self.get_ident(request)
    
    
    ### 3.5 全局配置
    

    在settings.py中设置rest framework相关配置项

    REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
    # "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
    "DEFAULT_THROTTLE_CLASSES": ["app01.utils.VisitThrottle", ],
    "DEFAULT_THROTTLE_RATES": {
    "xxx": "5/m",
    }
    }

    
    
    - **转自**:https://www.cnblogs.com/liwenzhou/p/9410737.html
  • 相关阅读:
    博客索引
    【转载】学习顺序:顶级会议 ----> 顶级期刊 ------> 基础教材(博客) / 论文复现
    【神游篇00】关于自己的日常学习记录
    【1】ML简介
    【2】Neural Network学习
    【1】NNDL简介
    【1】Deep Learning简介
    【1】PRML简介
    【1】BRML简介
    图集压缩,,命令行工具
  • 原文地址:https://www.cnblogs.com/xiaoqshuo/p/10032197.html
Copyright © 2011-2022 走看看