1. 程式人生 > >權限的設計分析和基本使用

權限的設計分析和基本使用

NPU spa 改變 __str__ 包含 陌生 access com 一個用戶

瀏覽目錄

  • 權限介紹
  • 權限在Django中的操作

權限介紹

1、什麽是權限

權限我們應該不陌生,不一樣的人權限不同,我們常說“官大一級壓死人”,就是說每一個職位權限不同。我們經常會碰到說必須是管理員才能操作,這就是管理員的一種權限。什麽是權限呢?總的來說,在我們項目中,就是一個包含正則表達式的URL就是一個權限。

我們簡稱為RBAC。(url base access control)。

2、作用

權限的作用,就是生成一個獨立的組件,我們想用時都可以用。

權限在Django中的操作

說了這麽多也不一定會用,下面我們來看一個在Django框架中的實例。

新建項目

我們新建一個project_rbac項目,再建兩個app分別為app01和rbac,app01專門放與項目相關邏輯方面的應用,而rbac專門放與權限相關的。

記得在settings.py中配置新建的項目。

配置app

技術分享圖片

配置靜態文件

STATIC_URL = ‘/static/‘

STATICFILES_DIRS=[
    os.path.join(BASE_DIR,"static")
]  

創建表關系

rbac.models.py

建三個類,五張表

# 用戶表
class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)
    roles = models.ManyToManyField(to="Role")      #用戶與角色是多對多的關系

    def __str__(self):
        return self.name


# 角色表
class Role(models.Model):
    title = models.CharField(max_length=32)
    permissions = models.ManyToManyField(to="Permission")    #角色與權限多對多的關系

    def __str__(self):
        return self.title

# 權限表
class Permission(models.Model):
    title = models.CharField(max_length=32)
    url = models.CharField(max_length=32)

    def __str__(self):
        return self.title

角色表和權限表是多對多的關系(一個角色可以有多個權限,一個權限可以對應多個角色)
用戶表和角色表是多對多的關系(一個用戶可以有多個角色,一個角色有多個用戶)  

基於admin錄入數據

- 先創建一個超級用戶 python3 manage.py createsuperuser
    - 用戶名 root
    - 密碼 123456
    - 在admin.py 中
        from rbac import models
        admin.site.register(models.Permission)
        admin.site.register(models.Role)
        admin.site.register(models.UserInfo)
      這樣的話上去的是英文的,如果你想讓中文顯示就在類中加一個類
        class Meta:
           verbose_name_plural = "權限表"
      - 當你給關聯字段錄入數據的時候會有錯誤提示,那麽在類中你的那個關聯字段在加一個屬性blank = True 可以為空
      permissions = models.ManyToManyField(to="Permission",verbose_name="具有的所有權限", blank=True)

登錄校驗

技術分享圖片
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
    {% load static %}
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="{% static "bs/css/bootstrap.css" %}">
    <style>
        .container{
            margin-top: 150px;
        }
    </style>
</head>
<body>



<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <div class="panel panel-primary">
                <div class="panel-heading">登錄頁面</div>
                <div class="panel-body">
                    <form action="" method="post">
                        {% csrf_token %}
                        <div class="form-group">
                            <label for="user">用戶名</label>
                            <input type="text" class="form-control" id="user" name="user" placeholder="請輸入用戶名">

                        </div>

                        <div class="form-group">
                            <label for="pwd">密碼</label>
                            <input type="password" class="form-control" id="pwd" name="pwd"  placeholder="請輸入密碼">
                        </div>


                        <input type="submit" class="btn btn-primary login_btn" value="登錄">
                    </form>

                </div>

            </div>
        </div>
    </div>
</div>
<script src="{% static ‘/js/jquery-3.2.1.min.js‘ %}"></script>
<script src="{% static ‘/bs/js/bootstrap.js‘ %}"></script>
</body>
</html>
login.html

在rbac應用下面新建service包,新建perssions.py.

def initial_session(user,request):
    ## 查詢當前登錄用戶的所有權限
    permissions = user.roles.all().values("permissions__url").distinct()  # 權限列表去重
    permission_list = []
    for item in permissions:  # 循環取到的所有權限
        permission_list.append(item["permissions__url"])  # 將該用戶的權限url添加到permission_list列表中
    print(permission_list)
    # 在session中註冊權限列表
    request.session["permission_list"] = permission_list
views.py視圖中
# 登錄
def login(request):
    if request.method == "POST":
        user = request.POST.get("user")  # 取到輸入的用戶名
        pwd = request.POST.get("pwd")  # 取到輸入的密碼

        user = UserInfo.objects.filter(name=user, pwd=pwd).first()  # 判斷該用戶是否存在於數據庫
        if user:  # 登錄成功
            # 在session中註冊用戶ID
            request.session["user_id"] = user.pk

            # 查詢當前登錄用戶的所有角色
            # user_list= user.roles.all()  #角色列表        <QuerySet [<Role: 保潔>, <Role: 銷售>]>

            # 查詢當前登錄用戶的所有權限
            initial_session(user,request)

            return HttpResponse("登錄成功")

    return render(request, "login.html")   

權限校驗

在rbac應用下面新建service包,新建rbac.py,作為中間件。

在settings中配置中間件。

技術分享圖片

rbac.py
import re
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect

‘‘‘中間件‘‘‘

class ValidPermission(MiddlewareMixin):
    def process_request(self, request):
        # 當前訪問路徑
        current_path = request.path_info

        ‘‘‘檢查是否屬於白名單‘‘‘
        valid_url_list = ["/login/", "/reg/", "/admin/.*"]  # 白名單列表
        for url in valid_url_list:  # 查看是否屬於白名單
            ret = re.match(url, current_path)  # 當前路徑與白名單列表做匹配
            if ret:  # 當前路徑屬於白名單
                return None  # 通過這個校驗

        ‘‘‘校驗是否登錄
            ‘‘‘
        user_id = request.session.get("user_id")  # 取到當前登錄用戶的id值
        if not user_id:  # 取不到id,說明沒登錄,跳轉到登錄頁面,重新登錄
            return redirect("/login/")

        ‘‘‘校驗權限‘‘‘
        permission_list = request.session.get("permission_list", [])
        flag = False  # 設置初始值
        for permission in permission_list:  # 循環權限列表,查看權限
            permission = "^%s$" % permission  # 字符串拼接重新定義權限
            ret = re.match(permission, current_path)  # 權限路徑與當前訪問路徑做匹配
            if ret:  # 匹配成功
                flag = True  # 改變狀態,跳出循環
                break
        if not flag:
            return HttpResponse("不好意思,您沒有訪問權限!")

        return None

 設置白名單,是指所有人都可以訪問的url。登錄校驗,在訪問某一些url時,只有登錄才能訪問,如果沒登錄,跳轉到登錄頁面。權限校驗,判斷當前登錄用戶有哪些權限,對於沒有該權限的用戶,是無訪問的。 

 

  

權限的設計分析和基本使用