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(中间有空格)
不然会获取不到用户哦~
原文地址:https://www.cnblogs.com/mapel1594184/p/13954340.html