1. 程式人生 > 實用技巧 >許可權管理---RBAC簡單許可權

許可權管理---RBAC簡單許可權

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]