RESF framework框架-权限源码流程解析

630 阅读3分钟

权限

这是我参与8月更文挑战的第24天,活动详情查看:8月更文挑战

感激相遇 你好 我是y大壮

作者:y大壮
链接:juejin.cn/user/756923… 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

🌊🌈关于前言:

文章部分内容及图片出自网络,如有问题请与我本人联系

🌊🌈关于内容:

1、自定义方式实现(基本使用):

我们一般在定义用户模型类的时候会定义一个用户类型,权限就是按照用户类型来大致实现

写权限类,通过获取数据库的用户类型返回True,False(True表示可以访问)

# app02.utils.permission.py

class Mypermission(object):
    """管理员"""

    def has_permission(self, request, value):
        if request.user.user_type == 2:
            return True
        return False


class Mypermission01(object):
    """普通用户管理用户都可以访问"""

    def has_permission(self, request, value):
        if request.user.user_type != 2:
            return True
        return True
# 使用
from .utils.permission import Mypermission01,Mypermission

class OrderView(APIView):
    permission_classes = [Mypermission01, ]
    def get(self, request, *args, **kwargs):
        ret = {'code': 200, 'message': 'ok!', 'data': None}  # 自己设置返回的消息,也可以直接用Response
        try:
            ret['data'] = ORDER_DICT
        except Exception as e:
            ret['code'] = 1001
            ret['message'] = '找不到服务器'
        return JsonResponse(ret)

自己设置返回的消息,也可以直接用Response

2、权限流程原理

  1. APIView下的dispatch

        def dispatch(self, request, *args, **kwargs):
    
  2. self.initial(request, *args, **kwargs) :认证方法

    def initial(self, request, *args, **kwargs):
        # 实现认证
        self.perform_authentication(request)
        # 权限判断
        self.check_permissions(request)
        self.check_throttles(request)
  1. self.check_permissions(request):权限判断

        def check_permissions(self, request):
            # self.get_permissions()权限类的对象 【对象1,对象2,】
            for permission in self.get_permissions():
                # 判读has_permission返回是True还是False
                if not permission.has_permission(request, self):  # 进入里面的代码就表示没有权限,输出错误信息(可以重写message和code)
                    self.permission_denied(
                        request,
                        message=getattr(permission, 'message', None),
                        code=getattr(permission, 'code', None)
                    )
    

3、自定义全局权限&局部权限

全局权限
  1. 写权限认证类

    # app02.utils.permission.py
    
    class Mypermission(object):
        """管理员"""
        message = '你没有权限'
        code = '1001'
    
        def has_permission(self, request, value):
            if request.user.user_type == 2:
                return True
            return False
    
    
    class Mypermission01(object):
        """普通用户管理用户都可以访问"""
    
        def has_permission(self, request, value):
            if request.user.user_type != 2:
                return True
            return True
    
  2. 在settings.py配置

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': ['app02.utils.auth.Authtication','app02.utils.auth.FirstAuthtication',],  # 认证
        # 'DEFAULT_AUTHENTICATION_CLASSES': ['app02.utils.auth.FirstAuthtication'],  # 匿名用户(因为我们在封装的时候什么都没有写,让它返回None)
        # 'UNAUTHENTICATED_USER': lambda: '匿名用户',
        'UNAUTHENTICATED_USER': None,
        'UNAUTHENTICATED_TOKEN': None,
        'DEFAULT_PERMISSION_CLASSES':['app02.utils.permission.Mypermission']  # 管理才可以访问(权限)
    }
    
  3. 使用

    视图函数就可以使用改权限
    
    如果不想使用直接     permission_classes = []
    
局部权限

​ 和上面的(1)一样

from .utils.permission import Mypermission01,Mypermission


class OrderView(APIView):
    permission_classes = [Mypermission01, ] # 局部
    def get(self, request, *args, **kwargs):
        ret = {'code': 1000, 'message': 'ok!', 'data': None}
        try:
            ret['data'] = ORDER_DICT
        except Exception as e:
            ret['code'] = 1001
            ret['message'] = '找不到服务器'
        return JsonResponse(ret)

4、权限Permissions(自带权限认证)

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。

  • 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
  • 在通过get_object()获取具体对象时,会进行对象访问权限的判断
  1. 在settings.py中配置

    # 可以在配置文件中设置默认的权限管理类,如
    
    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        )
    }
    # 如果未指明,则采用如下默认配置
    
    'DEFAULT_PERMISSION_CLASSES': (
       'rest_framework.permissions.AllowAny',
    )
    
  2. 视图中通过permission_classes属性来设置

    from rest_framework.permissions import IsAuthenticated
    from rest_framework.views import APIView
    
    class ExampleView(APIView):
        permission_classes = (IsAuthenticated,)
    
  3. 更多的权限

    # 提供的权限
    AllowAny 允许所有用户
    IsAuthenticated 仅通过认证的用户
    IsAdminUser 仅管理员用户
    IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取
    
  4. 示例

    举例
    from rest_framework.authentication import SessionAuthentication
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.generics import RetrieveAPIView
    
    class BookDetailView(RetrieveAPIView):
        queryset = BookInfo.objects.all()
        serializer_class = BookInfoSerializer
        authentication_classes = [SessionAuthentication]
        permission_classes = [IsAuthenticated]