• django restframework permission


    与 authentication 和 throttling 一起,permission 决定是应该接受还是拒绝访问请求。
    权限检查总是在视图的最开始处运行,在任何其他代码被允许进行之前。权限检查通常会使用 request.user 和 request.auth 属性中的认证信息来确定是否允许传入请求。
    权限用于授予或拒绝不同类别的用户访问 API 的不同部分。
    最简单的权限是允许通过身份验证的用户访问,并拒绝未经身份验证的用户访问。这对应于 REST framework 中的 IsAuthenticated 类。
    稍微宽松的权限会允许通过身份验证的用户完全访问,而未通过身份验证的用户只能进行只读访问。这对应于 REST framework 中的 IsAuthenticatedOrReadOnly 类。

    设置权限策略

    默认权限策略可以使用 DEFAULT_PERMISSION_CLASSES setting 全局设置。例如

    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        )
    }
    

    如果未指定,则此设置默认为允许无限制访问:

    'DEFAULT_PERMISSION_CLASSES': (
       'rest_framework.permissions.AllowAny',
    )
    

    当然也可以基于 APIView 类的视图上设置身份验证策略

    查看源码,restframework现成的类有7个,介绍如下常用四个

    AllowAny:允许无限制访问

    IsAuthenticated :允许访问任何经过身份验证的用户,并拒绝访问任何未经身份验证的用户

    IsAdminUser:允许超级用户访问

    IsAuthenticatedOrReadOnly:对经过身份验证的用户的允许完全访问,但对未经身份验证的用户的允许只读访问

    @six.add_metaclass(BasePermissionMetaclass)
    class BasePermission(object):
        """
        A base class from which all permission classes should inherit.
        """
    
        def has_permission(self, request, view):
            """
            Return `True` if permission is granted, `False` otherwise.
            """
            return True
    
        def has_object_permission(self, request, view, obj):
            """
            Return `True` if permission is granted, `False` otherwise.
            """
            return True
    

     但完全可以我们自己来写,仅需要面向上述源码任意一个接口即可。

    apps/app/permissions.py

    from rest_framework.permissions import BasePermission
    
    
    class IsLoginReadOnly(BasePermission):
        """
        自定义权限设置
        """
        def has_permission(self,request,view):
    
            return all((request.user.is_authenticated,request.user.is_staff))
    

    如果你需要测试请求是读取操作还是写入操作,则应该根据常量SAFE_METHODS检查请求方法,SAFE_METHODS是包含'GET''OPTIONS''HEAD'的元组 

    if request.method in permissions.SAFE_METHODS:
        # 检查只读请求的权限
    else:
        # 检查读取请求的权限
    

      

    views.py

    from rest_framework import mixins
    from rest_framework import viewsets
    
    from .models import UserProfile
    from .serializers import UserProfileSerializer
    from .permissions import IsAuthenticatedOrReadOnly
    
    
    class UsersListViewSets(viewsets.GenericViewSet,mixins.ListModelMixin):
        """
        用户列表
        """
        queryset = UserProfile.objects.all()
        serializer_class = UserProfileSerializer
        permission_classes = (IsAuthenticatedOrReadOnly,)
    

      

    对象级权限

    实际场景下,我们往往需要对权限细分:

    POST 请求要求用户对模型实例具有 add 权限。
    PUT 和 PATCH 请求要求用户对模型实例具有 edit 权限。
    DELETE 请求要求用户对模型实例具有 delete 权限。

    这就需要我们重写APIView下的has_permissions方法

    views.py

    from .permission import UserAddPermission
    from .permission import UserDeletePermission
    from .permission import UserEditPermission
    from .permission import UserQueryPermission
    
    # permission_classes = (UserQueryPermission,)
        def get_permissions(self):
            if self.action == "create":
                self.permission_classes = (UserAddPermission,)
            elif self.action == "list":
                self.permission_classes = (UserQueryPermission,)
            elif self.action == "update":
                self.permission_classes = (UserEditPermission,)
            elif self.action == "destroy":
                self.permission_classes = (UserDeletePermission,)
            return super().get_permissions()
    

    permission.py

    class UserAddPermission(BasePermission):
        """
        增加用户权限
        """
        def has_permission(self, request ,view):
            user = request.user
            if user.is_authenticated:
                permissons = user.has_permissons()
                return "add user" in permissons
    

     遇到了问题,即使UsersListViewSets继承了viewsets.ModelViewSet,该接口依旧只允许GET, POST, HEAD, OPTIONS四种方法,

    没有put和delete.

    解决:自己手动绑定。。。

        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
    
        def delete(self,request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    

      

  • 相关阅读:
    【设计模式】策略模式
    【设计模式】模板方法模式
    【C++】《Effective C++》第五章
    【C++】《Effective C++》第四章
    free命令详解(内存)
    top命令详解(动态进程)
    ps命令详解(静态进程)
    SpringBoot_集成Redis
    SpringBoot_热部署插件
    SpringBoot_实现RESTfull API
  • 原文地址:https://www.cnblogs.com/zenan/p/10523496.html
Copyright © 2020-2023  润新知