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

瀏覽目錄

 

權限介紹

一、什麼是權限

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

咱們簡稱爲RBAC。(url base access control)。html

二、做用

權限的做用,就是生成一個獨立的組件,咱們想用時均可以用。python

權限在Django中的操做

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

新建項目

咱們新建一個project_rbac項目,再建兩個app分別爲app01和rbac,app01專門放與項目相關邏輯方面的應用,而rbac專門放與權限相關的。正則表達式

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

配置app

配置靜態文件

STATIC_URL = '/static/'

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

建立表關係

rbac.models.pydjango

建三個類,五張表bootstrap

# 用戶表
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

角色表和權限表是多對多的關係(一個角色能夠有多個權限,一個權限能夠對應多個角色)
用戶表和角色表是多對多的關係(一個用戶能夠有多個角色,一個角色有多個用戶)  session

 基於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.app

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時,只有登陸才能訪問,若是沒登陸,跳轉到登陸頁面。權限校驗,判斷當前登陸用戶有哪些權限,對於沒有該權限的用戶,是無訪問的。 

相關文章
相關標籤/搜索