2016-09-28 87 views
7

我目前正在學習平均值堆棧,開發一個簡單的TODO的應用程序並希望爲此實現基於角色的訪問控制(RBAC)。我如何在MongoDB上設置角色&權限。MongoDB + Node基於角色的訪問控制(RBAC)

我想3個角色(角色可能看起來很有趣,但這純粹是爲了學習):

  • GOD
  • 超級英雄
  • MAN

GOD - 類似於超admin,可以在應用程序中做任何事情。 C,R,U,D權限也適用於TODO和其他用戶。可以創建TODO &直接將其分配給任何SUPER HERO或MAN。在任何時間點更新或刪除TODO或用戶。

SUPER HERO - 與admin類似,擁有超強的處理能力,可以爲TODO的個人數據--C,R,U,D做任何事情。無法創建任何用戶。只能閱讀&爲他/她添加由GOD &創建的TODO的評論。

MAN - 只能閱讀並添加評論給TODO分配給他/她的人。

概括起來:

GOD - C,R,U,D [Global Level] SUPER HERO - C,R,U,D [Private] + R,U [Assigned to him] MAN - R,U [Assigned to him]

我明白,我需要讓用戶& ROLES集合。如果ROLES inturn應該有PERMISSIONS等。我如何將它們全部連接起來?

回答

5

我喜歡給角色的名字 - GOD,超級英雄& MAN,容易理解。

由於您正在使用MEAN堆棧,並且大多數路由驗證發生在node上,所以我寧願讓角色表保持簡單。

角色:

{ 
_id : 1, 
name : GOD, 
golbalPerms : true 
}, 
{ 
_id : 2, 
name : SUPER HERO, 
privatePerms : true 
}, 
{ 
_id : 3, 
name : MAN 
} 

用戶:

{ 
_id : 111, 
name : Jesus, 
roleId : 1 
}, 
{ 
_id : 222, 
name : BatMan, 
roleId : 2 
}, 
{ 
_id : 333, 
name : Jack, 
roleId : 3 
} 

當發送user對象返回給客戶端用戶登錄,確保與DB相應role對象來代替roleId

來到代碼節點上的JS:

通過完全理解你的用例,我們可以將其分爲以下方法 -

  • CREATEUSER

  • CreateTodo

  • DeleteTodo

  • ReadTodo

  • UpdateTodo
  • CommentTodo

  • AssignTodo

讓去一步一步CREATEUSER

航線的代碼片段:

app.all('/users', users.requiresLogin); 

// Users Routes 
app.route('/users') 
    .post(users.hasPerms('globalPerms'), users.create); 

在你的控制器,你可以驗證基於輸入globalPerms,如果驗證允許通過調用next()其他return與相應的錯誤信息來創建用戶。

現在CreateTodo & & DeleteTodo

兩個人都在相同的邏輯相當多的工作有一個小竅門。

路由的代碼片斷:

app.all('/todos', users.requiresLogin); 

// Users Routes 
app.route('/todos') 
    .post(users.hasPerms('globalPerms','privatePerms'), todos.create); 
    .delete(users.hasPerms('globalPerms','privatePerms'), todos.delete); 

有關創建的Todo,globalPermsGOD & privatePerms超級英雄,它們兩者可以被允許。

把戲這裏會在todos.delete的方法,只是確保user.id === todos.createById否則超級英雄可能會繼續刪除上帝創造的待辦事項。

ReadTodo

TODO創建它應該有一個createById同樣存儲當TODO分配給別人,然後assignedToassignedBy也應該被記錄下來。

這使得很多其他操作很容易處理。

user.role.globalPerms - 給GOD所有TODO的數據。

user.role.privatePerms - 給予TODO或者由他/她創建或分配給他/她。

user.role.globalPerms === undefined && user.role.privatePerms === undefined - 它的MAN,並給TODO的只分配給他。

UpdateTodo & CommentTodo

這是什麼ReadTODO這樣做DIY

最後一個,AssignTodo翻版:

簡單的一個,loggedInUser.id === todos.createdById那麼他就可以把它分配給任何人。

兩件事情要記住這裏:

  1. 由於分配部件大多發生在你的UI(角)前,我已經給檢查loggedInUser.id === todos.createdById的這種做法。以任何方式登錄用戶將通過讀取操作看到所有TODO的,並可將其分配給他/她喜歡的任何人。

  2. 確保超級英雄只能分配一個TODO給他自己或其他超級英雄或一個人,但不能給上帝。你如何顯示分配給UI前端的選項不在這個問題的範圍之內。這只是一個提醒。

希望這是明確的。

注意:沒有必要爲角色集合中的MAN授予權限&我們管理了所有可能的操作。

+0

這是乾淨的n最好的解決方案,我可以要求使用任何第三方模塊。謝謝 :) – BeingSuman

0

可能approach->中嵌入用戶採集/架構角色: 用戶文件應具備以下條件:

{ 
    _id : "[email protected]", 
    name: "lorem ipsum", 
    role: "MAN" 
} 

至於你的文章描述,只有上帝才能和分配待辦事項。 角色集可以包含以下:

{ 
    _id : "MAN", 
    globalPerm: [], 
    privatePerm: [], 
    assignedPerm: ["r","u"], 
}, 
{ 
    _id : "SUPER_HERO", 
    globalPerm: [], 
    privatePerm: ["c","r","u","d"], 
    assignedPerm: ["c","r","u","d"], 
}, 
{ 
    _id : "GOD", 
    globalPerm: ["c","r","u","d"], 
    privatePerm: ["c","r","u","d"], 
    assignedPerm: ["c","r","u","d"], 
} 

節點JS中間件 得到正確的權限值用戶後,你可能想使用中間件。 示例表示HTTP請求路由:

app.post('/updateTodo', permissions.check('privatePerm', 'c'), function (req, res) { 
// do stuff 

};

在實際執行函數體來更新TODO之前調用permissions.check。

因此,如果用戶嘗試更新待辦事項,它將首先驗證相應的權限。

0

這是一個非常廣泛的問題,可以通過多種方式解決。

你已經添加了你正在使用MEAN棧,因此我會限制我的問題。你有沒有包含在整個問題

一件事是一種認證架構您使用的是什麼。假設您正在使用基於令牌的身份驗證,通常現在人們使用它。

我們有3種類型的用戶。 您可以使用不同的選項來區分令牌的類型。

  1. 不同採收(MongoDB的)或Redis的規定,他們將被存儲
  2. 的加密令牌將用戶的類型以及等。(這會派上用場,如果你不需要在後端存儲令牌,你可以解密並檢查)

    • 這完全取決於用例。

現在,允許任何用戶的入門用戶具體路線請確保您首先檢查令牌之前。

app.post('/godlevelroute', godtokencheck, callrouteandfunction); 
app.post('/superherolevelroute', superheroroute, callrouteandfunction); 

必須從角頭髮送令牌,然後你可以從頭部出來取數據,然後你可以檢查是否該特定用戶有權要經過這條路線與否。

比方說,在那麼神級用戶登錄,他將與他的godleveltoken,我們會允許他訪問的路線,否則你可以只顯示錯誤消息之前先檢查。

這可以在服務器端的樣本令牌檢查功能

function checkToken(req, res, next) { 
var token = req.headers['accesstoken']; //access token from header 
//now depending upon which system you are following you can run a check 
}; 

節點模塊建議:https://www.npmjs.com/package/jsonwebtoken

現在即將前端部分。您基於您寫的內容使用角度,您可以在顯示任何頁面之前攔截令牌。

你可以通過這個博客得到什麼,我試圖解釋的圖示。 Click Here

相關問題