• RABC权限管理


    1 RABC权限管理

    1.1 表关系分析

    1.2 表设计

    1.2.1 用户表

    账号、姓名、邮箱、添加时间、最后登录时间、账号是否禁止登录

    1.2.2 角色表

    商品管理员、订单管理员、超级管理员

    1.2.3 资源列表

    储存是路径正则

    资源分类:商品模块、订单模块、营销模块、权限模块、内容模块、其他模块

    1.2.4 权限表

    对某一个路由的增删改查

    # 源码分析
    class BasePermission(metaclass=BasePermissionMetaclass):
        """
        A base class from which all permission classes should inherit.
        """
    
        def has_permission(self, request, view):
            # has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
            """
            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
    

    1.3 具体分析

    1.3.1 如果只允许post方法访问
    • utils/Authentication.py
    class MyPermission(BasePermission):
        # 继承的一定要是rest_framework里面的BasePermission,类的名字随意
        # has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
        def has_permission(self, request, view):
            # 可以用request.user来获取用户名
            # 可以用request.method来查询访问的方式
            # 可以用request.path_info来查询访问的路由
            # 可以用 print(dir(request))来查看方法
            # 任何用户对使用此权限类的视图都有访问权限
            if request.method == 'post':
                print(request.method)
                if request.user.is_superuser:
                    return True
                elif view.kwags.get('pk') == str(request.user.id):
                    return True
            return False
        	# 访问的是get方法,所以直接走了False,不会执行下面的has_object_permission方法了!!!
            
            
    # has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
    # 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息
        def has_object_permission(self, request, view,obj):
            # 判断当前用户是否有访问 /course/sections/1/ 接口权限
            course_detail_url = re.match('/course/sections/(d+)/$', request.path_info)
            if course_detail_url:
                user = request.user
                course = obj.chapters.course
                has_video_rights = self.video_rights(user,course)
                return has_video_rights
            return True
    # 对用户是否有课程播放权限进行验证
        @staticmethod
        def video_rights(user,course):
            '''
            :param user: 当前登录用户
            :param course: 用户要播放的课程对象
            :return: 返回True有权限,否则出发异常
            '''
            # 1.免费课程直接返回True
            # 2.会员免费课程,判断当前用户是否是会员,如果是会员返回True
            # 3.付费课程,判断当前用户在UserCourse表中有购买记录返回True
            try:
                is_buy = UserCourse.objects.get(course=course, user=user)
                return True
            except Exception as e:
                raise exceptions.ParseError('没卖课程播放个毛线!头给你打扁!')
    
    • views.py
    from Authentication import MyPermission
    from rest_framework import viewsets
    
    
    class SectionsViewSet(viewsets.ModelViewSet):
        queryset = Sections.objects.all()
        serializer_class = SectionsSerializer
        permission_classes = (MyPermission, )
    
    • postman效果
    http://192.168.56.100:8888/course/sections/3/?id=3
    

    1.3.2 允许get访问
    • utils/Authentication.py
      • 第一个方法has_permission()整体跑通
    # -*- coding: utf-8 -*-
    import re
    
    from rest_framework.permissions import BasePermission
    from rest_framework import exceptions
    
    from course.models import UserCourse
    
    
    class MyPermission(BasePermission):
        # 继承的一定要是rest_framework里面的BasePermission,类的名字随意
        # has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
        def has_permission(self, request, view):
            print(dir(request))
            print(request.method)
            print(request.user)
            # 可以用request.user来获取用户名
            # 可以用request.method来查询访问的方式
            # 可以用request.path_info来查询访问的路由
            # 可以用 print(dir(request))来查看方法
            # 任何用户对使用此权限类的视图都有访问权限
            if request.method == 'GET':
                if request.user.is_superuser:
                    return True
                elif view.kwargs.get('pk') == str(request.user.id):
                    return True
            return False
    # has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
    # 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息
        def has_object_permission(self, request, view,obj):
            
            return True
    
    • views.py
    from Authentication import MyPermission
    from rest_framework import viewsets
    
    
    class SectionsViewSet(viewsets.ModelViewSet):
        queryset = Sections.objects.all()
        serializer_class = SectionsSerializer
        permission_classes = (MyPermission, )
    
    • postman效果
    http://192.168.56.100:8888/course/sections/3/?id=3
    

    1.3.3 没有购买订单
    • models.py
    # -*- coding: utf-8 -*-
    import re
    
    from rest_framework.permissions import BasePermission
    from rest_framework import exceptions
    
    from course.models import UserCourse
    
    
    class MyPermission(BasePermission):
        # 继承的一定要是rest_framework里面的BasePermission,类的名字随意
        # has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
        def has_permission(self, request, view):
            print(dir(request))
            print(request.method)
            print(request.user)
            # 可以用request.user来获取用户名
            # 可以用request.method来查询访问的方式
            # 可以用request.path_info来查询访问的路由
            # 可以用 print(dir(request))来查看方法
            # 任何用户对使用此权限类的视图都有访问权限
            if request.method == 'GET':
                if request.user.is_superuser:
                    return True
                elif view.kwargs.get('pk') == str(request.user.id):
                    return True
            return False
    # has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
    # 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息
        def has_object_permission(self, request, view,obj):
            # 判断当前用户是否有访问 /course/sections/1/ 接口权限
            course_detail_url = re.match('/course/sections/(d+)/$', request.path_info)
            if course_detail_url:
                user = request.user
                course = obj.chapters.course
                has_video_rights = self.video_rights(user,course)
                return has_video_rights
            return True
    # 对用户是否有课程播放权限进行验证
        @staticmethod
        def video_rights(user,course):
            '''
            :param user: 当前登录用户
            :param course: 用户要播放的课程对象
            :return: 返回True有权限,否则出发异常
            '''
            # 1.免费课程直接返回True
            # 2.会员免费课程,判断当前用户是否是会员,如果是会员返回True
            # 3.付费课程,判断当前用户在UserCourse表中有购买记录返回True
            try:
                is_buy = UserCourse.objects.get(course=course, user=user)
                return True
            except Exception as e:
                raise exceptions.ParseError('没买课程播放个毛线!头给你打扁!')
    
    
    • views.py
    from Authentication import MyPermission
    from rest_framework import viewsets
    
    
    class SectionsViewSet(viewsets.ModelViewSet):
        queryset = Sections.objects.all()
        serializer_class = SectionsSerializer
        permission_classes = (MyPermission, )
    
    • 第二个方法中由于数据库中没有数据,所以会走False

    • 显示没有购买,没办法观看
    http://192.168.56.100:8888/course/sections/3/?id=3
    

    1.3.4 购买才能访问
    • models.py
    # -*- coding: utf-8 -*-
    import re
    
    from rest_framework.permissions import BasePermission
    from rest_framework import exceptions
    
    from course.models import UserCourse
    
    
    class MyPermission(BasePermission):
        # 继承的一定要是rest_framework里面的BasePermission,类的名字随意
        # has_permission 是用户对这个视图有没有 GET POST PUT PATCH DELETE 权限的分别判断
        def has_permission(self, request, view):
            print(dir(request))
            print(request.method)
            print(request.user)
            # 可以用request.user来获取用户名
            # 可以用request.method来查询访问的方式
            # 可以用request.path_info来查询访问的路由
            # 可以用 print(dir(request))来查看方法
            # 任何用户对使用此权限类的视图都有访问权限
            if request.method == 'GET':
                if request.user.is_superuser:
                    return True
                elif view.kwargs.get('pk') == str(request.user.id):
                    return True
            return False
    # has_object_permission 是用户过了 has_permission 判断有权限以后,再判断这个用户有 没有对一个具体的对象有没有操作权限
    # 这样设置以后,即使是django admin管理员也只能查询自己user标的信息,不能查询其他用户的 单条信息
        def has_object_permission(self, request, view,obj):
            # 判断当前用户是否有访问 /course/sections/1/ 接口权限
            course_detail_url = re.match('/course/sections/(d+)/$', request.path_info)
            if course_detail_url:
                user = request.user
                course = obj.chapters.course
                has_video_rights = self.video_rights(user,course)
                return has_video_rights
            return True
    # 对用户是否有课程播放权限进行验证
        @staticmethod
        def video_rights(user,course):
            '''
            :param user: 当前登录用户
            :param course: 用户要播放的课程对象
            :return: 返回True有权限,否则出发异常
            '''
            # 1.免费课程直接返回True
            # 2.会员免费课程,判断当前用户是否是会员,如果是会员返回True
            # 3.付费课程,判断当前用户在UserCourse表中有购买记录返回True
            try:
                is_buy = UserCourse.objects.get(course=course, user=user)
                return True
            except Exception as e:
                raise exceptions.ParseError('没买课程播放个毛线!头给你打扁!')
    
    
    • views.py
    from Authentication import MyPermission
    from rest_framework import viewsets
    
    
    class SectionsViewSet(viewsets.ModelViewSet):
        queryset = Sections.objects.all()
        serializer_class = SectionsSerializer
        permission_classes = (MyPermission, )
    
    • 数据库中有数据

    • postman演示

    1.4 踩坑点

    # 常用问题:
    一定要注意,在用postman调试过程中,访问视图的时候,headers中加入token,格式是:
    Authorization:JWT token(中间有空格)
    不然会获取不到用户哦~
    
  • 相关阅读:
    【POJ 1958】 Strange Towers of Hanoi
    【HNOI 2003】 激光炸弹
    【POJ 3263】 Tallest Cow
    【POJ 2689】 Prime Distance
    【POJ 2777】 Count Color
    【POJ 1995】 Raising Modulo Numbers
    【POJ 1845】 Sumdiv
    6月16日省中集训题解
    【TJOI 2018】数学计算
    【POJ 1275】 Cashier Employment
  • 原文地址:https://www.cnblogs.com/mapel1594184/p/13954340.html
Copyright © 2020-2023  润新知