rbac(role-based access control,基於角色的訪問控制),就是使用者通過角色與許可權進行關聯。
在 django 中,許可權就是使用者對乙個包含正規表示式 url 有沒有訪問的權利。
在編寫程式過程中,要注重弱耦合,所以在建立專案之初,應當將 rbac 功能和邏輯功能分開來,建立不同的應用。
基於 rbac 的許可權管理最根本上需要對資料表進行更改。實現該方法需要五張表,使用者表,角色表,許可權表,使用者與角色關係表,角色與許可權關係表。
關於資料表的**如下。
class user(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
對使用者進行校驗的前提是使用者登入,並且使用者登入資訊瀏覽器要在其他頁面當中依然能夠取得,所以將使用者 id 存入 session 中。
在使用者登入時除了儲存使用者 id 資訊外,還應儲存使用者的所有許可權資訊。
登入檢視函式:
# 登入使用者存在
if user_obj:
# 將使用者id存入session
request.session["user_id"] = user_obj.pk
# 查詢當前登入使用者的所有許可權,註冊到session中
initial_session(user_obj, request)
return httpresponse("登入成功!")
return render(request, "login.html")
查詢並註冊使用者許可權資訊到 session 的**如下:
# /rbac/service/permission.py
def initial_session(user, request):
# 將使用者許可權列表存入session
# 取出登入使用者的許可權url並去重
# permissions = models.role.objects.filter(user=user_obj).values("permissions__url").distinct()
permissions = user.roles.all().values("permissions__url").distinct()
permission_list =
for item in permissions:
request.session["permission_list"] = permission_list
在 session 中儲存了使用者 id 資訊後判斷是否登入就很方便了:
# 校驗是否登入
if not request.session.get("user_id"):
return redirect('/login/')
前文中已經提到過,許可權就是帶正規表示式的 url ,對許可權進行校驗就是看當前 url 路徑是否在使用者許可權列表中,如果在則使用者有訪問該 url 的許可權。
其中,在判斷當前路徑是否在許可權列表中時應該使用正則匹配並注意要完全匹配,不能簡單的使用
元素 in 列表
這種簡單判斷。
# 當前路徑
current_path = request.path_info
# 校驗許可權
flag = false
permission_list = request.session.get("permission_list", )
for permission in permission_list:
# 保障url完全匹配
permission = "^%s$" % permission
ret = re.match(permission, current_path)
if ret:
flag = true
break
if not flag:
return httpresponse("沒有許可權訪問")
有了實現許可權校驗的**之後,如果想要在各個 url 中都進行校驗就需要在每個相應的檢視函式中填上相應的**,造成了**冗餘。
既然每個檢視函式都需要進行校驗,最好的辦法就是使用中介軟體,專案啟動後每次訪問 url 都會自動走該中介軟體,從而進行了許可權校驗。
有關中介軟體的知識請參考:django 中的中介軟體
# 校驗是否為白名單
valid_url_list = ["/login/", "/reg/", "/admin/.*"]
for item in valid_url_list:
ret = re.match(item, current_path)
if ret:
return none
中介軟體的完整**:
# 當前路徑
current_path = request.path_info
# 校驗是否為白名單
valid_url_list = ["/login/", "/reg/", "/admin/.*"]
for item in valid_url_list:
ret = re.match(item, current_path)
if ret:
return none
# 校驗是否登入
if not request.session.get("user_id"):
return redirect('/login/')
# 校驗許可權
flag = false
permission_list = request.session.get("permission_list", )
for permission in permission_list:
# 保障url完全匹配
permission = "^%s$" % permission
ret = re.match(permission, current_path)
if ret:
flag = true
break
if not flag:
return httpresponse("沒有許可權訪問")
基於thinkphp的RBAC許可權控制
rbac role based access control 許可權控制在後台管理中是十分常見的,它的模型大體上是下面這張圖的形式 我用的字段和上面不一樣,圖只是個示例 乙個簡易的許可權控制模型只需要3個表就行了 user表 記錄使用者的資訊和使用者的角色 user id 使用者的id user r...
基於角色的許可權訪問控制 RBAC
五個表 管理員表 z admin create table z admin id smallint 5 unsigned not null auto increment comment 管理員id username varchar 50 collate utf8mb4 unicode ci not ...
Nginx 基於Nginx的中介軟體架構
1 io 2 輕量級 3 cpu親和 affinity cpu親和 是一種把cpu核心和nginx工作程序繫結方式,把每個worker程序固定在乙個cpu上執行,減少切換的cachemiss,獲得良好的效能。4 sendfile 處理靜態檔案效率很高,因為他的傳輸機制是 sendfile。對比之前h...