簡體   English   中英

在 Express REST Api 中實現角色和權限的最佳方法是什么

[英]What is the best way to implement roles and permission in Express REST Api

我需要一些專家意見來在 Express js 中實現角色和權限。 我計划使用 Express js 開發 Restful Api,但沒有獲得足夠的信息來實現角色和權限,盡管有大量選項可用於身份驗證和授權。

創建表

首先,您需要創建將保存角色、權限和資源之間關聯的表:

  1. 創建角色表('Admin'、'User'、'Guest')
  2. 創建資源表(“用戶”、“項目”、“程序”)
  3. 創建權限表(“創建”、“讀取”、“寫入”、“刪除”、“拒絕”)
  4. 創建一個以所有三個表作為源的聯結表

您可能不需要權限表的那種粒度,但有些人喜歡它。 例如,您實際上並不需要“拒絕”,因為您只需檢查 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);

現在請記住,假設存在的每個角色都在角色集合中並且具有上述模式類型。

在對象的模式權限數組中,我們看到對象具有鍵:

  • 名稱(用於 url 的名稱,如“set-username”)
  • 路徑(對於基本路徑點擊“/users/”)
  • url (請求的 url 或完整路徑“/users/set-username”)

因此,如果具有角色user 的用戶有權更改用戶名,則他可以訪問 url /users/set-username但是,漫游者將無法訪問此 url。像 admin 和 superadmin 這樣的更高角色在邏輯上應該可以訪問所有較低的角色角色權限(網址)。

在實際應用中的作用是:-

  1. 流浪者剛剛訪問我們網站的人。他應該能夠訪問所有公共路線。所有人都可以訪問的簡單網址/公共網址因此不需要為此設置單獨的角色,因為它沒有任何經過身份驗證的權利。
  2. 來賓已注冊但未驗證的人說電子郵件未驗證)。
  3. 用戶擁有經過驗證的電子郵件的人
  4. 管理員經驗證后被超級管理員設為管理員。他享有大部分權限
  5. 超級管理員申請大師。他享有一些更復雜的權利。比管理員更多的權利

到目前為止,我們已經了解什么是正確的以及它如何映射到角色。


第 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 中,請遵循以下步驟:

  1. 將所有簡單的 urls(public) 和 Auth Urls(admin & users) & super-admin-specific urls 加載到 superAdminRights[] 中。
  2. 如果不存在,則運行一個函數來創建一個具有超級管理員角色的用戶。
  3. 如果找到,則獲取類型為:“superadmin”的角色:將其權限替換為新權限(superAdminRights)。否則:創建類型為:“superadmin”的角色,然后填寫其權限(superAdminRights)。

在此函數調用結束時,我們始終確保應用程序中有一個超級管理員,其所有復雜的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM