原文連接:BlueSun | 基於RESTful API 怎麼設計用戶權限控制?html
有人說,每一個人都是平等的;
也有人說,人生來就是不平等的;
在人類社會中,並無絕對的公平,
一件事,並非全部人都能去作;
同樣物,並非全部人都可以擁有。
每一個人都有本身的角色,每種角色都有對某種資源的必定權利,或許是擁有,或許只能是遠觀而不可褻玩。
把這種人類社會中如此抽象的事實,提取出來,而後寫成程序,還本來質的工做,就是咱們程序員該作的事了。
有了一個這麼有範兒的開頭,下面便來談談基於RESTful,如何實現不一樣的人不一樣的角色對於不一樣的資源不一樣的操做的權限控制。java
本文是基於RESTful描述的,須要你對這個有初步的瞭解。
RESTful是什麼?
Representational State Transfer,簡稱REST,是Roy Fielding博士在2000年他的博士論文中提出來的一種軟件架構風格。
REST比較重要的點是資源和狀態轉換,
所謂"資源",就是網絡上的一個實體,或者說是網絡上的一個具體信息。它能夠是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的實在。
而 "狀態轉換",則是把對應的HTTP協議裏面,四個表示操做方式的動詞分別對應四種基本操做:git
GET,用來瀏覽(browse)資源程序員
POST,用來新建(create)資源github
PUT,用來更新(update)資源web
DELETE,用來刪除(delete)資源數據庫
清楚了資源的概念,而後再來對資源進行一下分類,我把資源分爲下面三類:編程
私人資源 (Personal Source)restful
角色資源 (Roles Source)網絡
公共資源 (Public Source)
"私人資源":是屬於某一個用戶全部的資源,只有用戶本人才能操做,其餘用戶不能操做。例如用戶的我的信息、訂單、收貨地址等等。
"角色資源":與私人資源不一樣,角色資源範疇更大,一個角色能夠對應多我的,也就是一羣人。若是給某角色分配了權限,那麼只有身爲該角色的用戶才能擁有這些權限。例如系統資源只可以管理員操做,通常用戶不能操做。
"公共資源":全部人不管角色都可以訪問並操做的資源。
而對資源的操做,無非就是分爲四種:
瀏覽 (browse)
新增 (create)
更新 (update)
刪除 (delete)
角色和用戶的概念,自不用多說,你們都懂,可是權限的概念須要提一提。
"權限",就是資源與操做的一套組合,例如"增長用戶"是一種權限,"刪除用戶"是一種權限,因此對於一種資源所對應的權限有且只有四種。
角色與用戶的關係:一個角色對應一羣用戶,一個用戶也能夠扮演多個角色,因此它們是多對多的關係。
角色與權限的關係:一個角色擁有一堆權限,一個權限卻只能屬於一個角色,因此它們是一(角色)對多(權限)的關係
權限與用戶的關係:因爲一個用戶能夠扮演多個角色,一個角色擁有多個權限,因此用戶與權限是間接的多對多關係。
須要注意兩種特別狀況:
私人資源與用戶的關係,一種私人資源對應的四種權限只能屬於一個用戶,因此這種狀況下,用戶和權限是一(用戶)對多(權限)的關係。
超級管理員的角色,這個角色是神通常的存在,能無視一切阻礙,對全部資源擁有絕對權限,甭管你是私人資源仍是角色資源。
角色、用戶、權限的模型應該怎麼樣設計,才能知足它們之間的關係?
對上圖的一些關鍵字段進行說明:
name: 資源的名稱,也就是其餘模型的名稱,例如:user、role等等。
identity: 資源的惟一標識,能夠像uuid,shortid這些字符串,也能夠是model的名稱。
permissions : 一種資源對應有四種權限,分別對這種資源的browse、create、update、delete
source : 該權限對應的資源,也就是Source的某一條記錄的惟一標識
action :對應資源的操做,只能是browse、create、update、delete四個之一
relation:用來標記該權限是屬於私人的,仍是角色的,用於OwnerPolicy檢測
roles: 擁有該權限的角色
users : 角色所對應的用戶羣,一個角色能夠對應多個用戶
permissions: 權限列表,一個角色擁有多項權利
createBy : 該記錄的擁有者,在user標裏,通常等於該記錄的惟一標識,這一屬性用於OwnerPolicy的檢測,其餘私有資源的模型設計,也須要加上這一字段來標識資源的擁有者。
roles : 用戶所擁有的角色
在sails下稱爲策略(Policy),在java SSH下稱爲過濾器(Filter),不管名稱如何,他們工做原理是大同小異的,主要是在一條HTTP請求訪問一個Controller下的action以前進行檢測。因此在這一層,咱們能夠自定義一些策略/過濾器來實現權限控制。
爲行文方便,下面姑且容許我使用策略這一詞。
策略 (Policy)
下面排版順序對應Policy的運行順序
SessionAuthPolicy:
檢測用戶是否已經登陸,用戶登陸是進行下面檢測的前提。
SourcePolicy:
檢測訪問的資源是否存在,主要檢測Source表的記錄
PermissionPolicy:
檢測該用戶所屬的角色,是否有對所訪問資源進行對應操做的權限。
OwnerPolicy:
若是所訪問的資源屬於私人資源,則檢測當前用戶是否該資源的擁有者。
若是經過全部policy的檢測,則把請求轉發到目標action。
在Sails下,有一個很方便的套件sails-permissions,集成了一套權限管理的方案,本文也是基於該套件的源碼所引出來的權限管理解決方案。
對程序員最大的挑戰,並非可否掌握了哪些編程語言,哪些軟件框架,而是對業務和需求的理解,而後在此基礎上,把要點抽象出來,寫成計算機能理解的語言。
最後,但願這篇文章,可以幫助你對權限管理這一課題增長多一點點理解。
若是本文對您有用
請不要吝嗇大家的Follow與Start
這會大大支持咱們繼續創做
「Github」
MZMonster :@MZMonster
JC_Huang :@JerryC8080