• 六、python Django REST framework[认证、权限、限流]


    一、认证

    解释:认证有五大认证类: BasicAuthenticationSessionAuthenticationTokenAuthenticationRemoteUserAuthentication,他们都继承了BaseAuthentication

    认证流程代码:

    1. 先通过分发进入认证环节  def dispatch(self, request, *args, **kwargs):[rest_framework.views.py大约485行前后]
    2. 先通过request = self.initialize_request(request, *args, **kwargs)来获得一个新的request,里面已经读取过了配置信息,知道下面要用什么认证方式
    3. 该函数里面self.initial(request, *args, **kwargs)进入认证、权限、限流功能
    4. initial里面的self.perform_authentication(request)进行认证
    5. perform_authentication实际调用user()[rest_framework.requests.py大约220行前后]
    6. 由user里面的_authenticate进入到user_auth_tuple = authenticator.authenticate(self)这里开始的authenticate[rest_framework.authentication.py]开始根据配置选择认证方式
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用方法:

    解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

    • 全局配置
      • 写入setting.py文件
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.BasicAuthentication',  # Basic认证
            'rest_framework.authentication.SessionAuthentication',  # session认证
            'rest_framework.authentication.TokenAuthentication',  # session认证
            'rest_framework.authentication.RemoteUserAuthentication',  # session认证
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 局部配置
      • 写入views.py
    from rest_framework.authentication import SessionAuthentication, BasicAuthentication
    
    class TestGenericAPIView(ModelViewSet):
        authentication_classes = (SessionAuthentication, BasicAuthentication) # 写在这里
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1.基础认证

    1.1 BasicAuthentication

    认证方式原理:这种方式不需要Cookie和Session,只需要客户端发起请求的时候,在头部Header中提交用户名和密码(base64格式加密)。如果没有附加,会弹出一个对话框,要求输入用户名和密码。但是它不提供信息加密措施,通常都是以base64编码传输。

    好处:简单,不需要Cookie和Session,被广泛支持,一般用于内网比如路由器验证之类

    缺点:不安全不能保存信息,关闭浏览器即失效,不能自己退出,比较落后,信息很容易被篡改,目前并不是特别推荐使用

    源码简单分析:

    # 承接上面最初的第5步,开始根据配置选择认证方式
    1. 认证方式[rest_framework.authentication.py]的BasicAuthentication的authenticate()函数
    2. 在authenticate()里面调用auth = get_authorization_header(request).split()
    3. get_authorization_header()开始去获取header传来关于名称和密码的md5数据
    4. 在下面return self.authenticate_credentials(userid, password, request)[大约87]调用self.authenticate_credentials()
    5. 其中这个函数里面的authenticate()[大约98]开始查询数据库验证密码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1.2 SessionAuthentication

    session和cookie:cookie是储存在用户端即浏览器里面,session储存在服务器里面,cookie因为在用户端所以安全差,而且储存内容少,所以把关键内容写入到服务器专门创建的session表里面。当用户第一次请求,服务器就会在session表单里面写入(多个浏览器一个用户,算多次请求,过期或者退出,session可能会消失[依据不同处理逻辑来定]),之后每次请求都会验证是否第一次请求,如果不是则服务器会确定用户操作

    认证方式原理:比如用户登录之类都是用其来实现,其是通过验证用户登录后服务器发送给session表单新创建的id号写入cookie(里面有字段为),请求时携带着cookie,提取到服务器去获取cookie里面session的id然后去找到服务器里面的session表去获取里面储存的信息,获取用户身份信息进行验证。Django默认是这种方式

    优点:cookie能长期保存能退出,自主加密比较安全

    缺点:cookie不能跨域,服务器数据库保存cookie数据,用户多,服务器储存session压力压力大

    源码简单分析:

    # 承接上面最初的第5步,开始根据配置选择认证方式
    1. 通过user = getattr(request._request, 'user', None)获取request._request属性
    2. user属性相当于去获取requests.user这个方法相当于去读取cookie解密session并且去数据库里面提取出,当前的用户。
    
    • 1
    • 2
    • 3

    1.3 TokenAuthentication

    介绍:未来再介绍

    1.4 RemoteUserAuthentication

    介绍:未来再介绍

    二、权限

    基础认证类:

    • AllowAny 允许所有用户
    • IsAuthenticated 仅通过认证的用户
    • IsAdminUser 仅管理员用户
    • IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取

    使用方法:

    解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

    • 全局配置
      • 写入setting.py文件
    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 局部配置
      • 写入views.py
    from rest_framework.authentication import SessionAuthentication, BasicAuthentication
    
    class TestGenericAPIView(ModelViewSet):
        authentication_classes = (SessionAuthentication, ) # 认证方法选择
        permission_classes = (IsAuthenticated,) # 关键在这
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    自定义权限
    导入:from rest_framework.permissions import BasePermission
    解释:需要继承BasePermission,并重写has_permission'或者Falsehas_object_permission两个方法即可

    区别:has_permission 是用户可以对这个视图有没有 GET POST等权限进行区分,has_object_permission 是 has_permission返回True后,再判断这个用户有没有对一个具体的对象有没有操作权限

    class IsOwnerOrReadOnly(BasePermission):
        def has_permission(self, request, view):
            if request.method =="DELETE":
                return True
            elif request.method =="GET":
                return True
            else:
                return False
    
        def has_object_permission(self, request, view, obj):
            return False
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:关于has_object_permission()没有执行,通过翻看源码。①通过继承ModelViewSet类(里面又继承CreateModelMixin、UpdateModelMixin等等这些类,不知道看上篇文章),UpdateModelMixinRetrieveModelMixinDestroyModelMixin这三个类(做数据库变动操作和单一查询操作),其会在每次执行前调用self.get_object()该方法用来检查其是否存在,以及是否有操作权限(这就是关键),其在里面调用 self.check_object_permissions(self.request, obj)check_object_permissions又调用自己写的has_object_permission;②自己写修改、删除、单一查询要调用self.get_object()该方法,下面展示一段UpdateModelMixin的源代码方便学习self.get_object怎么用

    class RetrieveModelMixin:
        """
        Retrieve a model instance.
        """
        def retrieve(self, request, *args, **kwargs):
            instance = self.get_object()
            serializer = self.get_serializer(instance)
            return Response(serializer.data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    三、限流

    基础限制类:

    • AnonRateThrottle 限制未登录用户

    • UserRateThrottle 限制登录用户

    • ScopedRateThrottle 具体视图限制

    使用方法:

    解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

    • 限制登录与未登录

    导入:from rest_framework.throttling import UserRateThrottle

    # 当使用登录与未登录限制的时候,所有视图的访问都会被记录在内
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
            'rest_framework.throttling.UserRateThrottle'
        ),
        'DEFAULT_THROTTLE_RATES': {
            'anon': '100/day', # 未登录用户一天访问最多100次,anon是默认的
            'user': '1000/day'# 登录用户一天访问最多1000次
        } # 可以使用 second, minute, hour 或day来指明周期
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    class TestGenericAPIView(ModelViewSet):
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
        throttle_classes = (UserRateThrottle,) # 关键
    
    • 1
    • 2
    • 3
    • 4
    • 限制具体视图
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.ScopedRateThrottle', # 让其靠上先生效
            'rest_framework.throttling.AnonRateThrottle',
            'rest_framework.throttling.UserRateThrottle',
        ),
        'DEFAULT_THROTTLE_RATES': {
            'anon': '100/day', # 未登录用户一天访问最多100次,anon是默认的
            'user': '10/hour', # 登录用户一天访问最多1000次
            'do':'3/hour' # 关键
        },
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    class TestGenericAPIView(ModelViewSet):
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
        throttle_classes = (UserRateThrottle,) # 不加默认也有主要靠setting.py里面
        throttle_scope = 'do' # 单独视图限流关键
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    飞行堡垒系列_键盘灯开关
    【JavaScript】用类的操作对CSDN社区管理菜单栏优化
    kotlin之foreach跳出循环
    【周赛+双周赛20220904】T4
    Linux下C++编程-进度条
    机器学习课程复习——隐马尔可夫
    全志R128芯片RTOS调试指南
    Rancher集群之间ssh登录问题
    数据仓库建模自动化
    数据结构和算法复习:第一弹
  • 原文地址:https://blog.csdn.net/weixin_46765649/article/details/126237710