1. 程式人生 > >基於RESTful API 設計使用者許可權控制

基於RESTful API 設計使用者許可權控制

RESTful簡述

 

本文是基於RESTful描述的,需要你對這個有初步的瞭解。 RESTful是什麼? Representational State Transfer,簡稱REST,是Roy Fielding博士在2000年他的博士論文中提出來的一種軟體架構風格。 REST比較重要的點是資源和狀態轉換, 所謂"資源",就是網路上的一個實體,或者說是網路上的一個具體資訊。它可以是一段文字、一張圖片、一首歌曲、一種服務,總之就是一個具體的實在。 而 “狀態轉換”,則是把對應的HTTP協議裡面,四個表示操作方式的動詞分別對應四種基本操作:

  1. GET,用來瀏覽(browse)資源
  2. POST,用來新建(create)資源
  3. PUT,用來更新(update)資源
  4. DELETE,用來刪除(delete)資源

資源的分類及操作

清楚了資源的概念,然後再來對資源進行一下分類,我把資源分為下面三類:

  1. 私人資源 (Personal Source)
  2. 角色資源 (Roles Source)
  3. 公共資源 (Public Source)

“私人資源”:是屬於某一個使用者所有的資源,只有使用者本人才能操作,其他使用者不能操作。例如使用者的個人資訊、訂單、收貨地址等等。 “角色資源”:與私人資源不同,角色資源範疇更大,一個角色可以對應多個人,也就是一群人。如果給某角色分配了許可權,那麼只有身為該角色的使用者才能擁有這些許可權。例如系統資源只能夠管理員操作,一般使用者不能操作。 “公共資源”:所有人無論角色都能夠訪問並操作的資源。

而對資源的操作,無非就是分為四種:

  1. 瀏覽 (browse)
  2. 新增 (create)
  3. 更新 (update)
  4. 刪除 (delete)

角色、使用者、許可權之間的關係

角色和使用者的概念,自不用多說,大家都懂,但是許可權的概念需要提一提。

“許可權”,就是資源與操作的一套組合,例如"增加使用者"是一種許可權,"刪除使用者"是一種許可權,所以對於一種資源所對應的許可權有且只有四種。

角色與使用者的關係:一個角色對應一群使用者,一個使用者也可以扮演多個角色,所以它們是多對多的關係。

角色與許可權的關係:一個角色擁有一堆許可權,一個許可權卻只能屬於一個角色,所以它們是一(角色)對多(許可權)的關係

許可權與使用者的關係:由於一個使用者可以扮演多個角色,一個角色擁有多個許可權,所以使用者與許可權是間接的多對多關係。

 

需要注意兩種特別情況:

  1. 私人資源與使用者的關係,一種私人資源對應的四種許可權只能屬於一個使用者,所以這種情況下,使用者和許可權是一(使用者)對多(許可權)的關係。
  2. 超級管理員的角色,這個角色是神一般的存在,能無視一切阻礙,對所有資源擁有絕對許可權,甭管你是私人資源還是角色資源。

資料庫表的設計

角色、使用者、許可權的模型應該怎麼樣設計,才能滿足它們之間的關係?

對上圖的一些關鍵欄位進行說明:

Source

  • name: 資源的名稱,也就是其他模型的名稱,例如:user、role等等。
  • identity: 資源的唯一標識,可以像uuid,shortid這些字串,也可以是model的名稱。
  • permissions : 一種資源對應有四種許可權,分別對這種資源的browse、create、update、delete

Permission

  • source : 該許可權對應的資源,也就是Source的某一條記錄的唯一標識
  • action :對應資源的操作,只能是browse、create、update、delete四個之一
  • relation:用來標記該許可權是屬於私人的,還是角色的,用於OwnerPolicy檢測
  • roles: 擁有該許可權的角色

Role

  • users : 角色所對應的使用者群,一個角色可以對應多個使用者
  • permissions: 許可權列表,一個角色擁有多項權利

User

  • createBy : 該記錄的擁有者,在user標裡,一般等於該記錄的唯一標識,這一屬性用於OwnerPolicy的檢測,其他私有資源的模型設計,也需要加上這一欄位來標識資源的擁有者。
  • roles : 使用者所擁有的角色

策略/過濾器

在sails下稱為策略(Policy),在java SSH下稱為過濾器(Filter),無論名稱如何,他們工作原理是大同小異的,主要是在一條HTTP請求訪問一個Controller下的action之前進行檢測。所以在這一層,我們可以自定義一些策略/過濾器來實現許可權控制。

為行文方便,下面姑且允許我使用策略這一詞。

** 策略 (Policy) **

下面排版順序對應Policy的執行順序

  1. SessionAuthPolicy:

檢測使用者是否已經登入,使用者登入是進行下面檢測的前提。

  1. SourcePolicy:

檢測訪問的資源是否存在,主要檢測Source表的記錄

  1. PermissionPolicy:

檢測該使用者所屬的角色,是否有對所訪問資源進行對應操作的許可權。

  1. OwnerPolicy:

如果所訪問的資源屬於私人資源,則檢測當前使用者是否該資源的擁有者。

如果通過所有policy的檢測,則把請求轉發到目標action。

Sails下的許可權控制實現

在Sails下,有一個很方便的套件sails-permissions,集成了一套許可權管理的方案,本文也是基於該套件的原始碼所引出來的許可權管理解決方案。