drf权限(1)

流程

执行initial()方法

def initial(self, request, *args, **kwargs):
    """
    Runs anything that needs to occur prior to calling the method handler.
    """
    self.format_kwarg = self.get_format_suffix(**kwargs)

    # Perform content negotiation and store the accepted info on the request
    neg = self.perform_content_negotiation(request)
    request.accepted_renderer, request.accepted_media_type = neg

    # Determine the API version, if versioning is in use.
    version, scheme = self.determine_version(request, *args, **kwargs)
    request.version, request.versioning_scheme = version, scheme

    # Ensure that the incoming request is permitted
    # 身份认证
    self.perform_authentication(request)
    # 检查权限
    self.check_permissions(request)
    # 流量限速
    self.check_throttles(request)

执行check_permissions()方法

def check_permissions(self, request):
    """
    Check if the request should be permitted.
    Raises an appropriate exception if the request is not permitted.
    """

    # 1.循环对象get_permissions方法的结果,如果自己没有,则去父类寻找
    for permission in self.get_permissions():

        # 2.判断每个对象中的has_permission方法返回值(其实就是权限判断),这就是为什么我们需要对权限类定义has_permission方法
        if not permission.has_permission(request, self):
            # 3. 返回无权限信息,也就是我们定义的message共有属性
            self.permission_denied(
                request, message=getattr(permission, 'message', None)
            )

去循环遍历self.get_permissions方法的结果。

get_permissions()方法

def get_permissions(self):
    """
    Instantiates and returns the list of permissions that this view requires.
    """
    return [permission() for permission in self.permission_classes]

这里将类权限类实例化和认证一样,循环遍历获得每个认证类的实例,
返回实例列表生成式,如果在视图类中没有的写的话,就会去默认的setting配置中找

permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES

在check_permissions看到

if not permission.has_permission(request, self):
    self.permission_denied(
        request, message=getattr(permission, 'message', None)
    )

如果实例permission的has_permission方法为空,就执行permission_denied方法

self.permission_denied()

def permission_denied(self, request, message=None):
    """
    If request is not permitted, determine what kind of exception to raise.
    """
    # 如果不允许请求,请确定引发哪种异常。
    if request.authenticators and not request.successful_authenticator:
        raise exceptions.NotAuthenticated()
    # 如果定义了message属性,则抛出属性值
    raise exceptions.PermissionDenied(detail=message)

这里意思是请求不允许就抛异常,到这里其实就结束了
如果有这个权限认证就过,没有就抛出异常

内置权限验证类

rest_framework.permissions

##基本权限验证
class BasePermission(object)

##允许所有
class AllowAny(BasePermission)

##基于django的认证权限,官方示例
class IsAuthenticated(BasePermission):

##基于django admin权限控制
class IsAdminUser(BasePermission)

##也是基于django admin
class IsAuthenticatedOrReadOnly(BasePermission)


- 自定义权限流程
    - 继承BasePermission类(推荐)
    - 重写has_permission方法
    - has_permission方法返回True表示有权访问,False无权访问

.....等等

基本的权限类供我们一些基础需求,但是我们更多的是需要自己单独写权限。

下面我们看下使用方法,基本的单独写权限

使用方法

内部类使用

##单一视图使用,为空代表不做权限验证
class MenuViewSet(ModelViewSet, TreeAPIView):
    permission_classes = [MyPremission,]

全局使用

REST_FRAMEWORK = {
   #权限
    "DEFAULT_PERMISSION_CLASSES":['API.utils.permission.MyPremission'],
}

优先级

单一视图(内部类) > 全局配置(全局)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值