[英]What is the best way to implement roles and permission in Express REST Api
我需要一些專家意見來在 Express js 中實現角色和權限。 我計划使用 Express js 開發 Restful Api,但沒有獲得足夠的信息來實現角色和權限,盡管有大量選項可用於身份驗證和授權。
創建表
首先,您需要創建將保存角色、權限和資源之間關聯的表:
您可能不需要權限表的那種粒度,但有些人喜歡它。 例如,您實際上並不需要“拒絕”,因為您只需檢查 Read != true。
現在,當您想要某個角色對資源的權限時,您只需查找 role_id 和 resource_id 並檢查哪些權限設置為 true。
創建中間件
由於您使用的是 express,中間件將很容易添加。 例如,假設您有一個名為 users 的路由器:
users.post('/', getAuth, handleUserPost)
假設您在請求上有某種標記來標識發布帖子的用戶,並將用戶實例附加到請求對象,您可以執行以下操作:
getAuth = function (req, res, next) {
if(req.user) {
db.getPerms({role_id: req.user.role_id, resource_id: req.resource.id})
.then(function(perms){
var allow = false;
//you can do this mapping of methods to permissions before the db call and just get the specific permission you want.
perms.forEach(function(perm){
if (req.method == "POST" && perms.create) allow = true;
else if (req.method == "GET" && perms.read) allow = true;
else if (req.method == "PUT" && perms.write) allow = true;
else if (req.method == "DELETE" && perm.delete) allow = true;
})
if (allow) next();
else res.status(403).send({error: 'access denied'});
})//handle your reject and catch here
} else res.status(400).send({error: 'invalid token'})
}
該代碼僅針對此示例進行了粗略處理,因此我不會復制和粘貼它,但它應該可以為您提供正確的想法。
Node.js 中的角色權限
第 1 部分:什么是角色和權利?
角色權限的實現是任何軟件的重要組成部分。角色是一個職責位置,每個職責都享有賦予他們的一些權利。少數角色之間可能存在一些共同的權利,而一些權利可能嚴格屬於特定角色。
權限是角色被授權訪問的Url。因此有必要在db中創建集合來存儲角色的權限信息。 我們有角色集合模式
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const RoleSchema = new Schema({
roleId:{
type:String,
unique:true,
required:[true,"Role Id required"]
},
type:{
type:String,
unique:true,
required:[true,"Role type is required"]
},
rights:[{
name: String,
path: String,
url: String
}]
});
module.exports = Role = mongoose.model('role',RoleSchema);
現在請記住,假設存在的每個角色都在角色集合中並且具有上述模式類型。
在對象的模式權限數組中,我們看到對象具有鍵:
因此,如果具有角色user 的用戶有權更改用戶名,則他可以訪問 url /users/set-username
但是,漫游者將無法訪問此 url。像 admin 和 superadmin 這樣的更高角色在邏輯上應該可以訪問所有較低的角色角色權限(網址)。
在實際應用中的作用是:-
到目前為止,我們已經了解什么是正確的以及它如何映射到角色。
第 1.5 部分:注冊網址/配置網址
這里我們有一個名為registeredUrls.js 的文件,它類似於:
module.exports = {
simple:{
"/":[""],
'/users/':["login","register"],
},
auth:{
//admin
'/admin/': ['load-users' , 'set-new-password','delete-user'],
'/teacher/':["add-teacher","delete-teacher","edit-teacher"],
'/student/':["add-student","delete-student","edit-student","test-result"],
//user
'/test/':["view-test","submit-test"],
'/profile/': ['change-username', 'update-profile-data', 'set-new-password', 'upload-pic', 'update-social-links'],
'/teacher/':['load-teacher'],
'/student/':['load-student']
}
}
同樣 confgUrls.js
const configUrls= {
'/roles/': ['get-rights', 'create', 'update-rights', 'load', 'delete', 'assign']
}
module.exports = configUrls;
第 2 部分:創建超級管理員
這是應用程序最重要的部分。無論何時服務器第一次啟動或重新啟動/重啟都會發生此步驟。在 config/init.js 中,請遵循以下步驟:
在此函數調用結束時,我們始終確保應用程序中有一個超級管理員,其所有復雜的 url/權限都已初始化。
第 3 部分:超級管理員特定的 URL
這些是僅超級管理員享有的權利,必須與注冊的 url 文件並行保存在單獨的文件中。這些包括映射僅由超級管理員使用的路由的 url 權限。 在這里,我們有創建角色、加載角色、獲取角色 ID 的權限、角色 ID/角色類型的更新權限、將角色分配給用戶、刪除角色的路由。
對於代碼中的每個用戶,我們需要將他們的角色從訪客更改為用戶(例如在電子郵件驗證后)。或者通過超級管理員使用assign-role url 將訪客/用戶更改為管理員。然后使用路由更新權限更新管理員權限。
該過程確保每個角色都有一個集合文檔並在那里填充權限。
第 4 部分:身份驗證器中間件
這是我們RBACS邏輯的核心。這里我們使用一個遵循流程的中間件:
1. 用auth-urls(registeredUrls.js) & super-admin-specific-urls(confgUrls.js) 和不同的[SIMPLE_URLS] 中的簡單url 填寫[AUTH_URLS] 中所有需要認證的url。
2. 然后檢查是否 (AUTH_URLS.indexOf(request.url) > -1){3rd step} else if (SIMPLE_URLS.indexOf(request.url)>-1){那么它是公共 url 如此簡單允許 next()} else { 響應未知 url}
3. 在這一步中,我們知道在 AUTH_URLS 中請求的 url 因此需要令牌檢查授權令牌標頭,如果找到,然后從中提取令牌{4th step}。如果沒有找到授權標頭,則響應“所需令牌”/“未知”。
4. 令牌找到,現在驗證這個令牌是否有一個有效的會話。如果是 {5th step} else token session not found 再次登錄。 5. 驗證 jwt 令牌驗證它是否已驗證{6.step} 否則響應“無效的 jwt 令牌”。
6.直到現在正確的url請求&令牌會話存在&jwt有效令牌。現在使用會話中的角色類型信息(存儲在會話中是用戶和令牌的基本信息)在角色中找到這個用戶會話角色類型,因此我們有它權限[]。現在查看 request.url 是否包含在權限[]中。如果找到{7th step} else {reponse "role not found/unknown user"}。
7. 如果找到,則{可以訪問此 url next() } else { 響應“訪問被拒絕”}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.