位运算+数据库两种方式实现中间件权限操作
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'
]