權限組件之rbac

rbac:基於角色的權限訪問控制(Role-Based Access Control)。html

rbac的主要流程:給每一個角色賦予不一樣的權限,是這個角色的員工都有這個角色的全部權限。一個角色能夠有多我的員擔任,一個員工能夠擔任多個角色(好比部門經理、業務員等)。當員工成功登錄系統時,系統須要獲取這個員工的多有權限,並放到一個列表裏面。而後員工在訪問每一個權限url時,系統須要進行判斷該員工有沒有這個權限進行這項操做。如何判斷?就是循環這個員工的全部權限,看有沒有對應的權限。這裏用到了re模塊裏面的match方法。django

以下代碼:session

# 須要先登錄,拿到該員工的權限列表並去重
def
login(request): if request.method=="GET": return render(request,"login.html") else: user=request.POST.get("user") pwd=request.POST.get("pwd") user=UserInfo.objects.filter(name=user,pwd=pwd).first() if user: # 驗證成功以後作什麼? request.session["user_id"]=user.pk # 設置session # 當前登陸用戶的全部權限, distinct()是去掉重複的權限 permission_info=user.roles.all().values("permissions__url","permissions__title").distinct() temp=[] # 該員工的所有權限url列表 for i in permission_info: temp.append(i["permissions__url"]) request.session["permission_list"]=temp # {"user_id":1,"permission_list":['/users/','/orders/']} return HttpResponse("登陸成功!") else: return redirect("/login/")

 登錄成功以後,判斷查看用戶操做權限app

from django.shortcuts import HttpResponse

def users(request):
    # //users/
    current_path = request.path_info  # 拿到訪問的路徑
    permission_list = request.session.get("permission_list")  # 取session,從session表裏面取到這個員工的全部權限 ['/order/', '/users/']
if not permission_list: # 用戶沒有登錄,取不到權限列表
return HttpResponse("login.html") # /users/edit/3 爲何要用正則,由於/users/edit/3 與/users/edit/(/d+)不能直接匹配 import re flag = False # 加上標誌位 for permission_url in permission_list: ret = re.match(permission_url, current_path) # 用正則去匹配具體的路徑,成功則返回對象, 不然返回None if ret: # 若是返回對象 flag = True break if not flag: return HttpResponse("沒有訪問權限") return HttpResponse("用戶列表") # 有權限

 接下來經過中間件來實現這個功能url

再建立一個應用名字叫作rbac(固然也能夠放到同一個應用裏面),這個應用裏面建立一個包service,包裏建立一個名字爲permission_li.py的文件。spa

from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import  redirect,HttpResponse,render

class M1(MiddlewareMixin):
    def process_request(self,request):
        # //users/
        current_path = request.path_info  # 拿到訪問的路徑
        permission_list = request.session.get("permission_list")  # 從session表裏面取到這個員工的全部權限 ['/order/', '/users/']
        # /users/edit/3  爲何要用正則,由於/users/edit/3 與/users/edit/(/d+)不能直接匹配
        import re
        flag = False  # 加上標誌位
        for permission_url in permission_list:
            ret = re.match(permission_url, current_path)  # 用正則去匹配具體的路徑,成功則返回對象, 不然返回None
            if ret:  # 若是返回對象
                flag = True
                break
        if not flag:
            return HttpResponse("沒有訪問權限")

settings.py裏面code

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'rbac.service.permission_li.M1',  # 加在這裏
]

接下來的問題就是,加上中間件以後,登錄頁面也沒有權限訪問了。csrf

咱們添加白名單,登錄、註冊和admin頁面加里便可。htm

from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import  redirect,HttpResponse,render

class M1(MiddlewareMixin):
    def process_request(self,request):
        pass

        #/admin/login/?next=/admin/
        current_path = request.path_info

        valid_url_menu=["/login/","/reg/","/admin/.*"]
        import re
        for valid_url in valid_url_menu:
            ret=re.match(valid_url,current_path)
            if ret:
                return None

        permission_list = request.session.get("permission_list")
        if not permission_list:
            return redirect("/login/")
        # /users/edit/3
        import re
        flag = False
        for permission_url in permission_list:
            ret = re.match(permission_url, current_path)
            if ret:
                flag = True
                break
        if not flag:
            return HttpResponse("沒有權限")
相關文章
相關標籤/搜索