許可權管理---RBAC簡單許可權
阿新 • • 發佈:2020-12-16
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
# Create your models here.
# 角色表
class Role(models.Model):
name = models.CharField('角色名稱', max_length=32, unique=True)
class Meta:
db_table = 'tb_role'
# AbstractUser是django使用者元件裡的使用者模型類,繼承以後對原來的模型類進行改寫
# 使用者表
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、自定義訪問許可權
############################ userapp/permission.py ##########
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 # 獲取當前使用者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 # 獲取當前使用者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)
# 通過當前角色 獲取當前角色 i 可以訪問的所有路徑url資訊
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]