RBAC实现
首先创建表关系
from django.db import models # Create your models here from django.contrib.auth.models import AbstractUser from utils.BaseModel import BaseModel # Create your models here. class Vip(BaseModel): vip_choise = ( ('0', '普通用户'), ('1', '普通会员'), ('2', '高级会员'), ) title = models.CharField('vip名称', max_length=16) vip_type = models.CharField('Vip种类',choices=vip_choise ,max_length=4,default='0') desc = models.CharField('vip描述',max_length=255) period = models.IntegerField('有效期', default=365) class Meta: db_table = 'tb_vip' def __str__(self): return self.title class Role(models.Model): name = models.CharField('角色名称', max_length=32, unique=True) #AbstractUser是django用户组件里的用户模型类,继承以后对原来的模型类进行改写 class User(AbstractUser): phone = models.CharField('手机号',max_length=20,null=True) img = models.CharField(max_length=256,null=True) nick_name = models.CharField('昵称',max_length=20,null=True) address = models.CharField('地址',max_length=255,null=True) email = models.CharField('邮箱',max_length=255,null=True) vip = models.ForeignKey(Vip, on_delete=models.SET_NULL, default=None, null=True) vip_expiration = models.DateField('vip到期时间', blank=True, default=None, null=True) roles = models.ManyToManyField(Role, related_name='users') class Meta: db_table = 'tb_user' #权限对应路径 class URLInfo(models.Model): url = models.CharField('路径', max_length=128,null=True) desc = models.CharField('描述', max_length=32, null=True) roles = models.ManyToManyField(Role, related_name='urlinfos')
创建permission.py文件
permission.py from rest_framework.permissions import BasePermission from userapp.models import User, URLInfo #VIP匹配 class VIPPermission(BasePermission): message = '必须是VIP才能访问' def has_permission(self, request, view): print(request.user.id) user_obj = User.objects.filter(id=request.user.id).first() if user_obj.vip_id != 1: return False return True class SLYPermission(BasePermission): message = '当前用户没有访问权限' def has_permission(self, request, view): uid = request.user.id # 获取当前用户id #获取相应的用户信息 user_obj = User.objects.filter(id=uid).first() # 查询出该用户对应的角色 user_role_obj = user_obj.roles.all() print("该用户的所有角色:", user_role_obj) #获取请求的URL http://127.0.0.1:8000/course/course/ url = request.path_info #获取对应的请求方式 GET method = request.method #对路由进行拼接 # print(url + method) url_method = url + method # 查询当前请求路径是否在收据库中存在 url_obj = URLInfo.objects.filter(url=url_method).first() print("当前路由对应的url对象", url_obj) #判断路由和方法拼成后存不存在 if url_obj: url_rolds_obj = url_obj.roles.all() else: return False # 循环遍历该用户的所有角色 for i in user_role_obj: # 判断该用户拥有的角色 是否 存在当前路径对应的角色中 if i in url_rolds_obj: return True return False
使用:
from userapp.permission import SLYPermission class CourseTypeView(ModelViewSet):
#添加权限 permission_classes = [SLYPermission] #指定查询结果 queryset = Cmodels.CourseType.objects.all() #指定序列化器 serializer_class = Cserialzer.CourseTypeSer
Postman测试
登录无权限用户
登录授权用户 数据可查
数据库关联关系
1.添加需要权限的URL tb_urlinfo
2.角色表tb_role
进行关联
3角色表关联用户
这样在所有角色下的用户都具有对应的权限