1、RBAC模型
- RBAC模型(Role-Based Access Control:基于角色的访问控制)
- 就是用户通过角色与权限进行关联
- 简单的说,一个用户拥有若干角色,每个角色拥有若干权限
- 这样,就构成了**“用户-角色-权限”**的授权模型
- 在这种模型中,用户与角色之间,角色与权限之间,一般都是多对多关系
2、表设计
from django.db import models
from django.contrib.auth.models import AbstractUser
from utils.MyBaseModel import Base
class Role(models.Model):
name = models.CharField('角色名称', max_length=32, unique=True)
class Meta:
db_table = 'tb_role'
class User(AbstractUser):
phone = models.CharField('手机号', max_length=20, null=True)
img = models.ImageField(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'
def __str__(self):
return self.username
class UrlInfo(models.Model):
url = models.CharField('url', max_length=20, null=True)
desc = models.CharField('描述', max_length=128, null=True)
roles = models.ManyToManyField(Role, related_name='urlsinfo')
class Meta:
db_table = 'tb_urls'
def __str__(self):
return self.url
3、自定义访问权限
from rest_framework.permissions import BasePermission
from userapp.models import User, Role, UrlInfo
class SYLPermission(BasePermission):
message = '当前用户没有该权限进行访问'
def has_permission(self, request, view):
uid = request.user.id
user_obj = User.objects.filter(id=uid).first()
user_role_obj = user_obj.roles.all()
print("该用户的所有角色:", user_role_obj)
url = request.path_info
method = request.method
print(url + method)
url_obj = UrlInfo.objects.filter(url=url + method).first()
print("当前路由对应的url对象", url_obj)
if url_obj:
url_role_obj = user_obj.roles.all()
else:
return False
for i in user_role_obj:
if i in url_role_obj:
return True
return False
class SYLPermission2(BasePermission):
message = '当前用户没有该权限进行访问'
def has_permission(self, request, view):
uid = request.user.id
user_obj = User.objects.filter(id=uid).first()
user_role_obj = user_obj.roles.all()
print("该用户的所有角色:", user_role_obj)
url = request.path_info
method = request.method
request_url = url + method
print(request_url)
for i in user_role_obj:
print(i)
url_obj = i.urlsinfo.all()
for j in url_obj:
if request_url == j.url:
return True
return False
4、接口测试
from rest_framework.viewsets import ModelViewSet
from courseapp import models, serializers
from userapp.permission import SYLPermission, SYLPermission2
class CourseTypeView(ModelViewSet):
queryset = models.CourseType.objects.all()
serializer_class = serializers.CourserTypeSer
permission_classes = [SYLPermission2]