1. 程式人生 > >22-1 rbac權限設計

22-1 rbac權限設計

item clas word 去重 同步 mission tag 好的 執行

一 表結構設計

技術分享圖片
 1 from django.db import models
 2 
 3 # Create your models here.
 4 from django.db import models
 5 
 6 # Create your models here.
 7 
 8 
 9 # 用戶表
10 class UserInfo(models.Model):
11     username = models.CharField(max_length=16, verbose_name="用戶名")
12     password = models.CharField(max_length=32, verbose_name="
密碼") 13 roles = models.ManyToManyField(to="Role", null=True, blank=True) 14 # null=TRUE是告訴數據庫這個字段可以為空,blank=True告訴djangoadmin可以不填 15 16 # 顯示具體的內容 17 def __str__(self): 18 return self.username 19 20 # 讓字段顯示中文 21 class Meta: 22 verbose_name = "用戶表" 23 verbose_name_plural = verbose_name
24 25 26 # 角色 27 class Role(models.Model): 28 title = models.CharField(max_length=32, verbose_name="角色名稱") 29 permissions = models.ManyToManyField(to="Permission") 30 31 def __str__(self): 32 return self.title 33 34 class Meta: 35 verbose_name = "角色表" 36 verbose_name_plural = verbose_name
37 38 39 # 權限表 40 class Permission(models.Model): 41 title = models.CharField(max_length=16, verbose_name="權限名稱") 42 url = models.CharField(max_length=255, verbose_name="URL") 43 is_menu = models.BooleanField(default=False, verbose_name="可作為菜單展示") 44 icon = models.CharField(max_length=16, verbose_name="菜單圖標", null=True, blank=True) 45 46 def __str__(self): 47 return self.title 48 49 class Meta: 50 verbose_name = "權限表" 51 verbose_name_plural = verbose_name
View Code

二 創建rbac權限管理項目

1. 為了實現項目結構的解耦,把權限系統單獨寫成一個app
  1. 創建APP
Django中創建app的步驟
1. python manage.py startapp rbac 在terminal終端裏面運行
2. 在settings.py中註冊app
    rbac.apps.RbacConfig
2. 執行兩條命令,把表結構同步到數據庫把創建數據庫的語句寫在rbac的models文件裏
  1. python manage.py makemigrations
  2. python manage.py migrate
3. 錄入數據
  借助Django Admin
  Django admin的用法
  1. 創建超級用戶,用來登陸admin管理後臺
  python manage.py createsuperuser
  2. 將我們自己寫的表註冊到Django admin中
  在app/admin.py中按照固定的格式註冊model

如下:

 

 1 from django.contrib import admin
 2 from rbac import models
 3 # 註冊用戶表
 4 admin.site.register(models.UserInfo)
 5 #註冊角色表
 6 admin.site.register(models.Role)
 7 
 8 
 9 # 自定義一個權限管理類
10 class PermissionAdmin(admin.ModelAdmin):
11     # 告訴django admin在頁面上展示我這張表的那些字段
12     list_display = ["title","url","is_menu","icon"]
13     # 在列表頁面可以編輯url
14     list_editable = ["url","icon","is_menu"]
15 
16 
17 admin.site.register(models.Permission,PermissionAdmin)

三 權限的查詢

權限查詢的代碼最好能拿出來單獨封裝一個函數,這樣方便你以後可以直接用你寫的rbac這個權限管理

1 在rbac目錄下面新建一個python package 名字可以隨便叫,然後新建一個py文件,名字也可以隨便叫我這裏叫:permission.py

技術分享圖片
 1 from django.conf import settings
 2 
 3 
 4 def init_permission(request, user_obj):
 5     ‘‘‘
 6 在session中初始化權限信息和菜單信息的函數
 7     :param request: 請求對象
 8     :param user_obj:當前登錄用戶
 9     :return:
10     ‘‘‘
11 
12     # user_obj.roles.all()那到當前用戶的所有角色
13     ret = user_obj.roles.all().values("permissions__url",
14                                       "permissions__icon",
15                                       "permissions__is_menu",
16                                       "permissions__title"
17                                       ).distinct()  # 取到去重之後的權限
18     # 定義一個權限列表
19     permission_list = []
20     # 定義一個專門用來存放當前用戶菜單的列表
21     menu_list = []
22     for item in ret:
23         print(item)  # item是個大列表
24         permission_list.append({"permissions__url": item["permissions__url"]})  # 添加到權限列表
25         if item["permissions__is_menu"]:  # 如果為真
26             menu_list.append({
27                 "title": item["permissions__title"],
28                 "icon": item["permissions__icon"],
29                 "url": item["permissions__url"]
30             })
31 
32     # 將用戶權限列表信息,存到session中
33     request.session[settings.PERMISSION_SESSION_KEY] = permission_list
34     # 把當前用戶的所有菜單存放到sessioin
35     request.session[settings.MENU_SESSION_KEY] = menu_list
View Code

2 setting.py文件配置

# 設置白名單
PERMISSION_WHITE_URL=[
    "/login/",
    "/admin/.*",
]
#權限列表
PERMISSION_SESSION_KEY="permission_list"

#菜單列表
MENU_SESSION_KEY="menu_list"

四 權限校驗

應該將權限的校驗功能放在中間件中的process_request()方法

1 在rbac目錄下面新建一個python package包 middleware ,然後建一個rbac.py文件,名字可以隨便取

技術分享圖片
 1 ‘‘‘
 2 自定義rbac中間件
 3 ‘‘‘
 4 from django.utils.deprecation import  MiddlewareMixin
 5 from django.shortcuts import redirect,HttpResponse,render
 6 import re
 7 from django.conf import settings
 8 
 9 class RBACMiddleware(MiddlewareMixin):
10     def process_request(self,request):
11         ‘‘‘
12         自定義權限校驗的中間件
13         :param request: 請求對象
14         :return:
15         ‘‘‘
16         # 1 取到當前這次請求訪問的url是什麽
17         url=request.path_info   # request.get_full_path()
18         # 過濾白名單
19         for item in settings.PERMISSION_WHITE_URL:
20             reg="^{}$".format(item)
21             if re.match(reg,url):
22                 return None
23         # 取到當前用戶的權限列表
24         permission_list=request.session.get(settings.PERMISSION_SESSION_KEY,None)
25         # 進行權限校驗
26         if  permission_list is None:
27             # 用戶沒登錄
28             return redirect("/login/")
29         for i in permission_list:
30             reg="^{}$".format(i[permissions__url])
31             if re.match(reg,url):
32                 break
33         else:
34             return HttpResponse("你沒有此權限")
View Code

2 然後在setting.py文件裏註冊一下

rbac.middleware.rbac.RBACMiddleware,

五 項目登錄函數的引用就是導入剛才封裝好的初始化權限的函數

‘‘‘
跟用戶相關的視圖都寫在這裏
‘‘‘
from django.shortcuts import redirect, render, HttpResponse
from rbac.models import UserInfo
from rbac.service.permission import init_permission


def login(request):
    error_msg = ""
    if request.method == "POST":
        # 取用戶名和密碼
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        # 驗證
        user_obj = UserInfo.objects.filter(username=username, password=pwd).first()
        if user_obj:
            # 登錄成功
            # 調用封裝好的初始化函數裏面含有權限列表和顯示菜單
            init_permission(request,user_obj)

            return redirect("/customer/list/")
        else:
            error_msg = "用戶名或密碼錯誤"

    return render(request, "login.html")

六 頁面中引用模板語言

1 首先在rbac下面新建一個python packages名字為templatetags(名字必須是這個)然後新建一個py文件,名字隨意,我這裏叫ooxx

filename 就是將你返回的結果給那個頁面調用,show_menu就是你自定義的模板語言的名字

from django import template

from luffy_permission import settings

register = template.Library()


@register.inclusion_tag(filename="my_menu.html")
def show_menu(request):
# menu_list是你從session裏面獲取的用戶的菜單列表
menu_list
= request.session[settings.MENU_SESSION_KEY] return {"menu_list": menu_list} # 把menu_list返回給my_menu.html這個頁面

2 新建一個my_menu.html的文件,名字跟filename後面的一致,在rbac目錄下新建一個templates

這個裏面的menu_list就是你上面自定義的的返回結果,menu.icon代表是圖標字段,menu.title代表是菜單名字

1 {% for menu in menu_list %}
2     <a href="{{ menu.url }}" class="active">
3         <span class="icon-wrap"><i class="fa {{ menu.icon }}"></i></span> {{ menu.title }}</a>
4 
5 {% endfor %}

3 讓你真正給用戶看的html頁面去引用ooxx,就是在菜單的div裏面加上這個 request是show_menu的一個參數

      <div class="static-menu">
                {% load ooxx %}
                {% show_menu request %}

            </div>

七 rbac權限目錄結構

技術分享圖片

新的項目中如何引用rbac權限管理##########################################################


1. 拷貝rbac這個app到項目中
2. 把rbac/migrations目錄下的遷移記錄都刪掉
3. 在項目中註冊rbac這個app
4. 創建數據庫遷移(執行那兩條命令)

1. python manage.py makemigrations
2. python manage.py migrate

5. 註冊admin,錄入數據 --> 自動發現並錄入權限URL
6. 在登錄流程中初始化權限信息,配置登錄函數引用封裝好的初始化權限

技術分享圖片
from django.shortcuts import render, HttpResponse, redirect
from django.conf import settings
from rbac.service.permission import init_permission
from rbac.models import UserInfo


# Create your views here.
def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        pwd = request.POST.get("password")

        user_obj = UserInfo.objects.filter(username=username, password=pwd).first()
        if user_obj:
            # 登錄成功
            # 初始化權限信息
            init_permission(request, user_obj)
            return redirect("/book_list/")
    return render(request, "login.html")


def book_list(request):
    return render(request, "book_list.html")


def book_add(request):
    return render(request, "book_add.html")
View Code

7. 註冊中間件
8. 在settings.py中設置權限相關的配置項

# 設置白名單
PERMISSION_WHITE_URL=[
    "/login/",
    "/admin/.*",
]
#權限列表
PERMISSION_SESSION_KEY="permission_list"

#菜單列表
MENU_SESSION_KEY="menu_list"

9 在html列表頁面引用

   {% load ooxx %}
    {% show_menu request %}





22-1 rbac權限設計