角色
隨著應(yīng)用程序的應(yīng)用范圍和用戶群體的增長,您可能會發(fā)現(xiàn)自己需要比用戶鏈接式ACL能提供的訪問數(shù)據(jù)分片更粗粒度的控制。為了解決這個(gè)問題,Parse支持一種基于角色的訪問控制。角色提供了一種邏輯的方式,將用戶按照對Parse數(shù)據(jù)具有共同訪問權(quán)限進(jìn)行分組。角色是包含用戶和其他角色的命名對象。授予角色的任何權(quán)限都會隱式授予其用戶以及其包含的任何角色的用戶。
例如,在具有策劃內(nèi)容的應(yīng)用程序中,您可能會有多個(gè)被認(rèn)為是“版主”的用戶,并且可以修改和刪除其他用戶創(chuàng)建的內(nèi)容。您可能還有一組用戶是“管理員”,并且允許與版主具有相同的權(quán)限,但也可以修改應(yīng)用程序的全局設(shè)置。通過將用戶添加到這些角色,您可以確保新用戶可以成為版主或管理員,而無需為每個(gè)用戶的每個(gè)資源手動授予權(quán)限。
我們提供一個(gè)稱為Parse.Role的專門的類,在客戶端代碼中體現(xiàn)這些角色對象。Parse.Role是Parse.Object的一個(gè)子類,具有所有Parse.Object相同的特性,如靈活的Schema模式、自動持久化和鍵值接口。Parse.Object所有的方法也存在于Parse.Role。不同之處在于,Parse.Role具有一些用于角色管理的額外特性。
1.Parse.Role 屬性
Parse.Role有幾個(gè)有別于Parse.Object的屬性:
- name:角色的名稱。此值是必需的,只能在創(chuàng)建角色時(shí)設(shè)置一次。名稱必須包含字母數(shù)字字符,空格, - 或_。該名稱將用于識別角色,而不需要其objectId。
- users:一組用戶上的關(guān)系,這些用戶將繼承授予給本角色的權(quán)限。
- roles:一組角色上的關(guān)系,這些角色以及其中的用戶將繼承授予給本角色的權(quán)限。
2.Role對象的安全性
Parse.Role使用與Parse中所有其他對象相同的安全模型(訪問控制列表),不同的是它需要顯式設(shè)置ACL。通常,只有具有極高等級權(quán)限的用戶(例如主用戶或管理員)才能創(chuàng)建或修改角色,因此您需要相應(yīng)地定義其ACL。請記住,如果您向用戶授予寫入Parse.Role的權(quán)限,那么該用戶可以將其他用戶添加到角色中,甚至完全刪除角色。
要?jiǎng)?chuàng)建一個(gè)新的Parse.Role,可以這樣寫:
// By specifying no write privileges for the ACL, we can ensure the role cannot be altered.
var roleACL = new Parse.ACL();
roleACL.setPublicReadAccess(true);
var role = new Parse.Role("Administrator", roleACL);
role.save();
您可以添加用戶和角色,他們通過Parse.Role上的“用戶”和“角色”關(guān)系繼承新角色的權(quán)限:
var role = new Parse.Role(roleName, roleACL);
role.getUsers().add(usersToAddToRole);
role.getRoles().add(rolesToAddToRole);
role.save();
為角色分配ACL時(shí),請務(wù)必小心,以便只使得具有修改權(quán)限的用戶能夠修改角色。
3.其他對象的基于角色的安全
現(xiàn)在,您已經(jīng)在應(yīng)用程序中創(chuàng)建了一組可用的角色,您可以用它們與ACL一起定義用戶將獲得的權(quán)限。每個(gè)Parse.Object都可以指定一個(gè)Parse.ACL,它提供一個(gè)訪問控制列表,指示哪些用戶和角色應(yīng)被授予對對象的讀取或?qū)懭霗?quán)限。
給一個(gè)角色賦予讀取或?qū)懭雽ο蟮臋?quán)限很簡單。你可以使用Parse.Role:
var moderators = /* Query for some Parse.Role */;
var wallPost = new Parse.Object("WallPost");
var postACL = new Parse.ACL();
postACL.setRoleWriteAccess(moderators, true);
wallPost.setACL(postACL);
wallPost.save();
您可以通過指定ACL的名稱來避免查詢角色:
var wallPost = new Parse.Object("WallPost");
var postACL = new Parse.ACL();
postACL.setRoleWriteAccess("Moderators", true);
wallPost.setACL(postACL);
wallPost.save();
4.角色的繼承層級
如上所述,一個(gè)角色可以包含另一個(gè)角色,從而在兩個(gè)角色之間建立父子關(guān)系。這種關(guān)系的結(jié)果是,授予父角色的任何權(quán)限被隱式授予其所有子角色。
這些類型的關(guān)系通常在具有用戶管理內(nèi)容(如論壇)的應(yīng)用程序中找到。一小部分用戶是“管理員”,擁有調(diào)整應(yīng)用程序的設(shè)置、創(chuàng)建新的論壇、設(shè)置全局消息等操作的最高權(quán)限。另一組用戶是“版主”,以負(fù)責(zé)確保用戶創(chuàng)建的內(nèi)容仍然恰如其分的使用。任何具有管理員權(quán)限的用戶也應(yīng)授予版主的權(quán)限。要建立這種關(guān)系,您可使“管理員”角色作為“版主”的子角色,如下所示:
var administrators = /* Your "Administrators" role */;
var moderators = /* Your "Moderators" role */;
moderators.getRoles().add(administrators);
moderators.save();