rbac 角色權(quán)限控制

Role Based Access Control,基于角色的權(quán)限控制,用于計(jì)算機(jī)操作系統(tǒng)的安全性控制

組件

多個(gè)插件組合到一起的部件,用于實(shí)現(xiàn)一系列相關(guān)功能. 例如:form組件

插件

僅僅實(shí)現(xiàn)一個(gè)小功能 比如: 分頁

權(quán)限組件

實(shí)現(xiàn)思路: 用戶--->職位(角色)--->權(quán)限

表結(jié)構(gòu)設(shè)計(jì)

1. 僅設(shè)計(jì) 權(quán)限表和用戶表
權(quán)限表 id url
用戶表 id name pwd .....
[ 關(guān)系:多對多, 一個(gè)人要有多個(gè)權(quán)限( 查看,修改的權(quán)限 ),且一個(gè)權(quán)限可以被多個(gè)人使用 ]

缺點(diǎn):這種關(guān)系是繁瑣的:一個(gè)職員的離職和入職,都需要?jiǎng)h除和添加這個(gè)職員和權(quán)限的關(guān)系

2.我們引入了角色的概念
權(quán)限表 路由 標(biāo)題
用戶表 姓名 密碼
角色表 名稱
[ 用戶和角色是多對多的關(guān)系(要有兼職的概念) ; 權(quán)限和角色也是多對多的關(guān)系(BOSS和銷售都要有 的權(quán)限),而BOSS不可能只有 的權(quán)限 ]

一定要注意:權(quán)限的重疊

流程
  1. 首先要記錄每個(gè)用戶的權(quán)限
    1. 登錄注冊功能
  2. 用戶登錄的時(shí)候,校驗(yàn)用戶的路由
    1. 登錄完成時(shí),將用戶的權(quán)限儲(chǔ)存到session中,方便快速獲取校驗(yàn)
    2. 登錄完成后,要校驗(yàn)用戶訪問的路由,不能超出權(quán)限,所以我們要利用中間件,在訪問之前完成校驗(yàn)
  3. 如果超出權(quán)限,拋出異常
實(shí)踐
記錄用戶權(quán)限

在 django 項(xiàng)目中創(chuàng)建并注冊一個(gè)app

簡單示例:
class Permission(models.Model):
    '''
    權(quán)限表
    '''
    url = models.CharField('權(quán)限', max_length=32)
    title = models.CharField('標(biāo)題', max_length=32)


    def __str__(self):
        return self.title


class Role(models.Model):
    '''
    角色表
    '''
    name = models.CharField('角色名稱', max_length=32)
    permissions = models.ManyToManyField('Permission', verbose_name='角色擁有的權(quán)限', blank=True)

    def __str__(self):
        return self.name


class User(models.Model):
    '''
    用戶表
    '''
    name = models.CharField('用戶名', max_length=32)
    pwd = models.CharField('密碼', max_length=32)
    roles = models.ManyToManyField('Role', verbose_name='用戶擁有的角色', blank=True)

    def __str__(self):
        return self.name

我們進(jìn)入應(yīng)用下的 admin 文件中,用Django 提供的基于 web 的管理工具

from django.contrib import admin
from rbac import models  # 導(dǎo)入表結(jié)構(gòu)

class PermissionAdmin(admin.ModelAdmin):
    list_display = ['url', 'title', ]  # 顯示字段
    list_editable = ['title', ]    # 修改字段

# 創(chuàng)建的三個(gè)表
admin.site.register(models.Permission, PermissionAdmin)
admin.site.register(models.Role)
admin.site.register(models.User)

隨后登錄 admin 錄入數(shù)據(jù)

登錄
def login(request):
    '''登錄'''
    msg = ''
    if request.method == 'POST':
        user = request.POST.get('username')
        pwd = request.POST.get('pwd')
        #  通過用戶名和密碼找到 用戶對象
        user_obj= models.User.objects.filter(name=user,pwd=pwd).first()
        if user_obj:
            # 進(jìn)行 ORM 操作
            通過對象找到角色,再通過角色找到權(quán)限.. '注意要去重:去除重復(fù)權(quán)限'
            ret = obj.roles.filter(permissions__url__isnull=False).values( xxx ).distinct()
            # 將權(quán)限列表保存到session中
            request.session[settings.PERMISSION_SESSION_KEY] = permission_list
            return redirect('customer_list')
        msg = '用戶名或密碼錯(cuò)誤'
    return render(request,'login.html',{'msg':msg})
校驗(yàn)

在用戶訪問之前判斷是否超出自己的權(quán)限,所以我們將權(quán)限的校驗(yàn),放置到中間件中

  1. 獲取當(dāng)前訪問的路由
  2. 設(shè)置白名單
  3. 判斷是否登錄,如果沒有重定向到登錄界面
  4. 免認(rèn)證( 有一些頁面,需要登錄但是不需要校驗(yàn),比如游客瀏覽的首頁 )
  5. 獲取當(dāng)前用戶的權(quán)限信息
  6. 循環(huán)校驗(yàn)
    1)對比成功 有權(quán)限 return
    2)不成功 沒有權(quán)限 return HttpResponse(‘沒有權(quán)限’)
    其中第3、4 步可以省略不寫;還有注意中間件的注冊
from django.utils.deprecation import MiddlewareMixin  # 導(dǎo)入中間件
from django.shortcuts import HttpResponse
from django.conf import settings  # 將session的key保存到配置文件中,做常量,防止修改,而獲取不到
import re  # 進(jìn)行正則匹配


class Rbac_Middlewar(MiddlewareMixin):
    def process_request(self, request):

        # 獲取當(dāng)前的路由
        url = request.path_info

        # 白名單( 在 settings 中)
        for i in settings.WHITE_LIST:
            if re.match(i, url):
                retur

        # 獲取當(dāng)前用戶的權(quán)限
        Permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)

        # 進(jìn)行校驗(yàn)
        for i in Permission_list:
            if re.match('^{}$'.format(i["url"]), url):
                return

        return HttpResponse('校驗(yàn)shibai')

注意事項(xiàng)

  1. form表單的 input 框一定要有名字,否則你無法獲取數(shù)據(jù)的內(nèi)容
  2. ORM 的增刪改查
  3. 在錄入權(quán)限的路由時(shí),注意輸入含有正則的字符串

比如 修改權(quán)限: 路由可以寫作 /customer/edit/(\d+)/ , \d+ 可以表示被修改者的id

  1. 中間件的注冊
  2. re模塊的應(yīng)用 math( 正則,字符串 )
  3. 當(dāng)將 session 的鍵,作為常量寫到 settings 配置文件中時(shí),那么在模板中,無法獲取到用戶的權(quán)限,因?yàn)?模板語法僅支持點(diǎn)語法,沒有 [ ] 的概念 ,所以我們可以通過 inclusion_tag 來返回自定義標(biāo)簽
 # 將權(quán)限列表保存到session中 
request.session[settings.PERMISSION_SESSION_KEY] = permission_list

# inclusion_tag 流程
1.  創(chuàng)建一個(gè)
2.  創(chuàng)建一個(gè) 自定義py文件
3.  進(jìn)行編寫基礎(chǔ)代碼
from django import template
register = template.Library()


@register.inclusion_tag('menu.html')
def menu(request):

    menu_dic = request.session.get(settings.MENU_SESSION_KEY)
    print(menu_dic)

    return {'menu_dic': menu_dic}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容