位运算+数据库两种方式实现中间件权限操作

1 数据库实现权限操作

  • 既是管理又是超级管理员的需要五表关联

1.1 四表联动

1.2 表设计

  • models.py
# 权限系统四标关联:角色表、用户表、节点表、权限表

# 角色表
class RoleModel(models.Model):
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=100, null=True)

    class Meta:
        db_table = 'role_model'


# 用户表
class UserModel(models.Model):
    username = models.CharField(max_length=30, unique=True, verbose_name='唯一注册用户名')
    password = models.CharField(max_length=256)
    role = models.ForeignKey(RoleModel, on_delete=models.CASCADE)

    class Meta:
        db_table = 'user_model'


# 节点表
class NodeModel(models.Model):
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=100, null=True)

    class Meta:
        db_table = 'node_model'


# 权限表
class Authority(models.Model):
    role_id = models.ForeignKey(RoleModel, on_delete=models.CASCADE)
    node_id = models.ForeignKey(NodeModel, on_delete=models.CASCADE)

    class Meta:
        db_table = 'authority'

1.3 所需参数

  • role.id(用户角色id)
  • type(前端节点类型)

1.4 middleware.py

from django.utils.deprecation import MiddlewareMixin


# --------------------------------------四表联合判断权限 middleware
class ChooseMiddleWare(MiddlewareMixin):
    def process_request(self, request):
        path = request.path_info
        if path in ('/user/test/'):
            user_info = decodeToken(request)
            role_id = user_info.get('role_id')
            node_id = Authority.objects.filter(role_id_id=role_id).first().node_id_id
            # 根据前端设置的传递类型来选择
            t = request.GET.get('type')
            # t ---------------> str
            if int(t) == node_id:
                pass
            else:
                return HttpResponse('拦截')
        else:
            pass

1.5 settings.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # mysql middleware
    # 'userapp.middlewares.VisitInfoMysqlMiddleWare',
    # redis middleware
    # 'userapp.middlewares.VisitInfoRedisMiddleWare',
    # mongo middleware
    # 'userapp.middlewares.VisitInfoMongoMiddleWare',
    # userinfo middleware
    'userapp.middlewares.ChooseMiddleWare',
    # 'userapp.middlewares.ChooseMiddleWareB'
    ]

2 二进制位运算实现权限操作

2.1 位运算前言

  • 十进制换成二进制,bin(10) ————————> ob1010

  • python中用 0b表示二进制。逢 2 进 1

  • 0b010 只有第二个有权限

  • 一样就是1, 不一样就是0

  • django内的操作都是二进制流的操作

  • 位运算权限,采用的是内置节点!

  • 位运算和科学计算相比,位运算性能更好!

0b001 & 0b010

0

0b001 & 0b001

1

100 & 1

0

101 & 1

1

0b10 & 0b01

0

0b11 & 0b01

1

2.2 表设计

  • 只需要两张表
# 角色表
class RoleModel(models.Model):
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=100, null=True)

    class Meta:
        db_table = 'role_model'


# 用户表
class UserModel(models.Model):
    username = models.CharField(max_length=30, unique=True, verbose_name='唯一注册用户名')
    password = models.CharField(max_length=256)
    role = models.ForeignKey(RoleModel, on_delete=models.CASCADE)

    class Meta:
        db_table = 'user_model'

2.3 middleware.py

# 中间件---------------------------------------------------------------------------------
from django.utils.deprecation import MiddlewareMixin
 

class ChooseMiddleWareB(MiddlewareMixin):
    def process_request(self, request):
        path = request.path_info
        if path in ('/user/test/'):

            # 这里设置位运算,默认权限对应关系是      role_id   拥有权限   权限id  ? 这样只能比对,做不了增值,可以倒过来想!
            #                                    1 ----------------- 1  0b100
            #                                    2 ----------------- 2  0b010
            #                                    3 ----------------- 3  0b001
            # 这里我想考虑一个角色多个权限的设置
            # 如果一个角色同时拥有两个或三个(此次设置三个权限)呢?存在什么关系?(可以进行权限叠加啊,后续研究),利用循环,看多少个权限?
            #   role_id         拥有权限        权限id
            #      1                            1     0b001             1
            #      1                            2     0b010 (+1)       2
            #      1                            1,2   0b011 (+2)        3
            #      1                            3     0b100 (+3)       4
            #      1                            1,3   0b101 (+4)       5
            #      1                            2,3   0b110 (+5)       6
            #      1                           1,2,3  0b111 (+6)       7
            #  所以给用户设定权限就可以了,这里给用户设定权限,角色1 全有 则为7, 角色2 有12权限 则为3, 角色3 只有第三个权限,则为4
            type = int(request.GET.get('type'))
            user_info = decodeToken(request)
            print(user_info)
            role_id = user_info.get('role_id')
            # 角色1 拥有权限
            # first_permision = 0b111
            # # 角色2 拥有权限
            # second_permision = 0b011
            # # 角色3 拥有权限
            # third_permision = 0b100
            # 相加就能看到共有几种权限啦!
            # 我们给角色1设定有三种权限,角色2设定有一,二两种权限,角色3设定只有第三种权限
            permision_dic = {1: 0b111, 2: 0b011, 3: 0b100}
            type_dic = {1: 0b001, 2: 0b010, 3: 0b100}
            if type_dic[type] & permision_dic[role_id] == 0:
                return HttpResponse('没有权限访问')

2.4 settings.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # mysql middleware
    # 'userapp.middlewares.VisitInfoMysqlMiddleWare',
    # redis middleware
    # 'userapp.middlewares.VisitInfoRedisMiddleWare',
    # mongo middleware
    # 'userapp.middlewares.VisitInfoMongoMiddleWare',
    # userinfo middleware
    # 'userapp.middlewares.ChooseMiddleWare',
    'userapp.middlewares.ChooseMiddleWareB'
    ]
原文地址:https://www.cnblogs.com/mapel1594184/p/14169413.html