[Python自学] restframework (4) (权限组件和频率组件)

一、权限组件

1.权限组件介绍

权限组件和认证组件的工作流程是基本相同的,可以参照 [Python自学] restframework (3) (认证组件) 中的流程。

2.为User表添加权限

# 用户表
class User(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    type_choices = ((1, "普通用户"), (2, "VIP"), (3, "SVIP"))
    # 默认用户类型都是普通用户
    user_type = models.IntegerField(choices=type_choices, default=1)

执行命令:

python manage.py makemigrations
python manage.py migrate

3.实现权限验证类

在utils.py中实现:

# utils.py

from rest_framework.permissions import BasePermission
from .models import User


class SVIPPermission(BasePermission):
    def has_permission(self, request, view):
        # 因为在验证token的时候,request.user已被赋值,所以可以从这里获取用户名
        user = request.user
        # 获取该用户的用户类型
        user_type = User.objects.filter(username=user.username).first().user_type
        if user_type == 3:
            return True  # 如果权限正确,则通过
        else:
            return False  # 权限不正确,则验证失败

将其应用到某个视图类,例如AuthorViewSet:

from .utils import SVIPPermission


class AuthorViewSet(viewsets.ModelViewSet):
    permission_classes = [SVIPPermission]

    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers

注意,在权限组件使用之前,应该还需要认证组件,这里的认证组件是在settings中配置的。

4.测试

使用Postman先登录,获取token:

{"code": 1000, "msg": null, "token": "81ba24601ce5be47ff2d96142a8ccb76"}

然后拿着token来获取books的数据:

[{"id":8,"publish":"http://127.0.0.1:8000/publishes/1/","title":"Python2标准库3","price":99,"pub_date":"2012-11-20T13:03:33Z","authors":[1,2]},{"id":9,"publish":"http://127.0.0.1:8000/publishes/1/","title":"Python2标准库4","price":99,"pub_date":"2012-11-20T13:03:33Z","authors":[1,2]},{"id":10,"publish":"http://127.0.0.1:8000/publishes/1/","title":"Python2标准库5","price":99,"pub_date":"2012-11-20T13:03:33Z","authors":[1,2]},{"id":11,"publish":"http://127.0.0.1:8000/publishes/1/","title":"Python2标准库6","price":99,"pub_date":"2012-11-20T13:03:33Z","authors":[1,2]},{"id":12,"publish":"http://127.0.0.1:8000/publishes/1/","title":"Python2标准库7","price":99,"pub_date":"2012-11-20T13:03:33Z","authors":[1,2]},{"id":13,"publish":"http://127.0.0.1:8000/publishes/1/","title":"Python2标准库","price":99,"pub_date":"2012-11-20T13:03:33Z","authors":[1,2]},{"id":14,"publish":"http://127.0.0.1:8000/publishes/1/","title":"Python3","price":99,"pub_date":"2020-01-20T13:03:04Z","authors":[3]},{"id":15,"publish":"http://127.0.0.1:8000/publishes/1/","title":"JAVA","price":99,"pub_date":"2020-01-20T13:03:04Z","authors":[3]},{"id":16,"publish":"http://127.0.0.1:8000/publishes/1/","title":"JAVA","price":99,"pub_date":"2020-01-20T13:03:04Z","authors":[3]},{"id":17,"publish":"http://127.0.0.1:8000/publishes/1/","title":"JAVA","price":99,"pub_date":"2020-01-20T13:03:04Z","authors":[3]},{"id":18,"publish":"http://127.0.0.1:8000/publishes/1/","title":"hello","price":99,"pub_date":"2020-01-20T13:03:04Z","authors":[3]}]

然后获取authors的数据:

{"detail":"You do not have permission to perform this action."}

由于leokale的用户类型是"普通用户",所以权限无法通过,则无法获取authors的数据。

修改detail提示信息:

class SVIPPermission(BasePermission):
    message = "只有超级用户才能访问"
    def has_permission(self, request, view):
        # 因为在验证token的时候,request.user已被赋值,所以可以从这里获取用户名
        user = request.user
        # 获取该用户的用户类型
        user_type = User.objects.filter(username=user.username).first().user_type
        if user_type == 3:
            return True  # 如果权限正确,则通过
        else:
            return False  # 权限不正确,则验证失败

我们在数据库中将leokale用户的用户类型修改为"SVIP":

然后,再次获取authors的数据:

[{"id":1,"name":"leo","age":32},{"id":2,"name":"alex","age":35},{"id":3,"name":"Jone","age":23},{"id":5,"name":"李雷","age":90}]

成功获取到数据。

5.全局配置

和认证组件一样,如果想对所有视图类进行权限验证,也可以在settings中的REST_FRAMEWORK进行配置:

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["demo.utils.TokenAuth"],
    "DEFAULT_PERMISSION_CLASSES":["demo.utils.SVIPPermission"]
}

二、频率组件

1.频率组件介绍

频率组件用来控制单位时间的访问频率,如果超过访问次数,则不允许访问,例如1分钟20次。工作过程和认证组件以及权限组件都是一样的。

2.需要实现一个频率检测类

from rest_framework.throttling import BaseThrottle


class VisitRateThrottle(BaseThrottle):
    def allow_request(self, request, view):
        # 这里判断是否超出频率阈值
        # 例如以ip为键,判断某个ip在1分钟内的访问次数
        # 或者以用户名为键
        # 统计一分钟内的访问次数
        stat = True
        if stat:
            return True
        else:
            return False

将其应用到某个视图类,例如AuthorViewSet:

class AuthorViewSet(viewsets.ModelViewSet):
    permission_classes = [SVIPPermission]
    throttle_classes = [VisitRateThrottle]
    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers

(¬‿¬)

猜你喜欢

转载自www.cnblogs.com/leokale-zz/p/12238026.html