什么是基于角色的权限管理?
在我们写项目时,可能会遇到需要给不同的用户分配不同的权限的情况,什么是权限呢?权限其实就是一个url
,不同的url代表不同的功能,限定用户能访问的url,就给了用户不同的权限
,权限管理在很多项目中都有用到,所以我们可以将权限管理的逻辑写成一个组件,使它在不同的项目中只要经过一定的修改就能使用。
RBAC权限模型
用户角色表和角色权限表都是
ManyToMany
,要实现效果至少需要4张表(一个人只能有一个角色的情况下),一般情况下,使用下面的模型。
建表
下面的资源表就是权限表
用户表、角色表、资源表、角色-资源表(ManyToMany
)
# models.py
from django.db import models
class Roles(models.Model):
"""
角色表
"""
name = models.CharField(max_length=32, verbose_name='角色名')
status = models.BooleanField(default=True, verbose_name='状态')
class Meta:
db_table = 'roles'
def __str__(self):
return self.name
class AdminUser(models.Model):
"""
管理员用户表
"""
username = models.CharField(max_length=32, verbose_name='用户名')
password = models.CharField(max_length=128, verbose_name='密码')
head = models.CharField(max_length=256, verbose_name='头像')
status = models.BooleanField(default=True, verbose_name='状态')
is_supper = models.BooleanField(default=False, verbose_name='是否超级用户')
role = models.ForeignKey(Roles, on_delete=models.CASCADE, verbose_name='角色')
class Meta:
db_table = 'adminUser'
def __str__(self):
return self.username
class Resourse(models.Model):
"""
资源表
"""
name = models.CharField(max_length=32, verbose_name='用户名')
status = models.BooleanField(default=True, verbose_name='状态')
url = models.CharField(max_length=128, verbose_name='url')
level = models.IntegerField(verbose_name='资源等级')
pid = models.ForeignKey('self', on_delete=models.SET_NULL, null=True,blank=True, related_name='subs')
roles = models.ManyToManyField(Roles, related_name='resources', blank=True)
class Meta:
db_table = 'resources'
def __str__(self):
return self.name
构造数据
在用户登录成功以后,根据用户的角色,分配相应的资源(
url
),这样的话就实现了权限管理。
class LoginView(APIView):
"""
登录接口
"""
def get(self, request):
"""
登录成功的资源
:param request:
:return:
"""
user_id = request.query_params.get('user_id')
user_obj = AdminUser.objects.filter(pk=user_id).first()
role_obj = Roles.objects.filter(id=user_obj.role_id).first()
# 查询角色对应的资源
res_obj = role_obj.resources.all()
# 父类列表
parent_list = []
# 父类id列表
parent_id_list = []
for i in res_obj:
parent_dict = {}
parent_dict['id'] = i.pid.id
parent_dict['name'] = i.pid.name
parent_dict['pic'] = i.pid.pic
parent_dict['subs'] = []
if i.pid.id not in parent_id_list:
parent_list.append(parent_dict)
parent_id_list.append(i.pid.id)
# 当父id等于父类列表的id,在父类列表下加子类
parent = []
returnlist = []
for i in parent_list:
parent = i
for j in res_obj:
if i['id'] == j.pid.id:
dict = {}
dict['id'] = j.id
dict['name'] = j.name
dict['url'] = j.url
parent['subs'].append(dict)
returnlist.append(parent)
return Response({'resources': returnlist})
效果展示
总结
RBAC的核心思想就是
限定用户能访问的url,给用户不同的权限
。