摘要:權限中心的依賴聲明聲明依賴關系檢查代碼規范聲明開發依賴命名空間檢查代碼規范,執行單元測試。單元測試持續交付一切都如此的完美,沒有測試,又如何可以證明這件事情的完美,又如何可以保障交付的質量。
序
權限管理是無線運營系統中的核心模塊,通過訪問控制策略的配置,來約定人與資源的訪問關系。
本文著重講解如何通過PHP來構建一個靈活、通用、安全的權限管理系統。
關于權限首先我們來聊聊權限。
權限系統一直以來是我們應用系統不可缺少的一個部分,若每個應用系統都重新對系統的權限進行設計,以滿足不同系統用戶的需求,將會浪費我們不少寶貴時間,所以花時間來設計一個相對通用的權限系統是很有意義的。
系統目標:對應用系統的所有對象資源和數據資源進行權限控制,比如 應用系統的功能菜單、各個界面的按鈕、數據顯示的列以及各種行級數據 進行權限的操控。
權限模型設計初期,我們學習了Amazon的 IAM ,經過對比分析,最終我們選用 RBAC3模型 來指導系統的設計工作。
RBAC認為權限授權實際上是Who、What、How的問題。在RBAC模型中,who、what、how構成了訪問權限三元組,也就是“Who對What(Which)進行How的操作”。
Who:權限的擁用者或主體(如Principal、User、Group、Role、Actor等等)
What:權限針對的對象或資源(Resource、Class)。
How:具體的權限(Privilege,正向授權與負向授權)。
Operator:操作。表明對What的How操作。也就是Privilege+Resource
Role:角色,一定數量的權限的集合。權限分配的單位與載體,目的是隔離User與Privilege的邏輯關系.
PHP架構之道「如何用PHP構建我們的權限中心」
接下來我們將從 編碼規范、依賴管理、數據源架構、數據處理、單元測試 等方面來體驗一把PHP的神奇之旅。
編碼規范好的編碼規范可以改善軟件的可讀性,可以促進團隊成長,可以減少Bug,可以降低維護成本,可以。。。(這么X,我們必須要推廣)
PHP社區一直百花齊放,擁有大量的函數庫、框架和組件,因而PHP代碼遵循或盡量接近同一個代碼風格就非常重要。
框架互操作組(即PHP標準組)發布了一系列推薦風格。
閱讀PSR-0
閱讀PSR-1
閱讀PSR-2 Coding Style Guide
閱讀PSR-4 Autoloader
權限中心的目錄結構:
-- /tuniu/rbac |-- src | |-- App //應用建模層 | | |-- City.php | | |-- Cms.php | | |-- Menu.php | |-- App.php | |-- Auth.php | |-- Orm //ActiveRecord層 | | |-- App | | | |-- Resource | | | | |-- Map.php | | | |-- Resource.php | | | |-- User.php | | |-- App.php | | |-- Log.php | | |-- Role | | | |-- User.php | | |-- Role.php | | |-- Rule.php | | |-- User.php | |-- Orm.php | |-- Utils.php |-- tests //測試 | |-- bootstrap.php | |-- fixtures | | |-- null.yml | | |-- rbac | | | |-- app.yml | | | |-- auth.yml | | | |-- role.yml | |-- rbac | | |-- appTest.php | | |-- authTest.php | | |-- roleTest.php |-- vendor |-- composer.json |-- composer.lock |-- phpunit.xml |-- README.md
PSR-2,權限應用資源類:
namespace TuniuRbacOrmApp; use TuniuRbacOrm; use TuniuRbacOrmApp; use TuniuRbacOrmAppResourceMap; use TuniuRbacOrmRule; use TuniuRbacOrmUser; class Resource extends Orm {}
PSR-4,命名空間的約定:
類名 | 文件路徑 |
---|---|
TuniuRbacOrmAppResource | /tuniu/rbac/src/Orm/App/Resource.php |
TuniuRbacAppCms | /tuniu/rbac/src/App/Cms.php |
Composer 是PHP中用來管理依賴(dependency)關系的工具。你可以在自己的項目中聲明所依賴的外部工具庫(libraries),Composer會幫你安裝這些依賴的庫文件。
權限中心的依賴聲明:
{ "name": "tuniu/rbac", "require": { //聲明依賴關系 "php": ">=5.3.0", "squizlabs/php_codesniffer": "2.*", //PHP_CodeSniffer檢查代碼規范 "php-activerecord/php-activerecord": "dev-master" //ActiveRecord }, "require-dev": { //聲明開發依賴 "phpunit/phpunit": "~4.6", "phpunit/dbunit": ">=1.2" }, "autoload": { "psr-4": { "TuniuRbac": "src/" //命名空間 } } }
檢查代碼規范,執行單元測試。
$./vendor/bin/phpcs --config-set default_standard PSR2 $./vendor/bin/phpcs src $./vendor/bin/phunit
^^^^^^ 眼澀,眼酸,眼疲勞,怎么辦。。。
騷年,如果舒服了,就使勁往下滑動吧。。。
數據源架構爭渡,爭渡,驚起一灘鷗鷺。
基于權限中心各表的關系(各種關聯,各種回調),采用傳統的模式,必將把精力耗在無盡的循環中。
于是乎,開始尋覓一種數據源的架構模式,Active Record很靠譜的出現了。
Active Record(中文名:活動記錄)是一種領域模型模式,特點是一個模型類對應關系型數據庫中的一個表,而模型類的一個實例對應表中的一行記錄。
PHP ActiveRecord 是一個基于ActiveRecord設計模式開發的開源PHP/ORM庫。它旨在大大簡化與數據庫的交互和減少手寫SQL語句。它不同于其他的ORM,你不需要使用任何的代碼生成器,也不費勁去手寫、維護模型層的表映射文件。這個庫的靈感來自Ruby on Rails,因此它也借鑒Ruby on Rails的想法和實現。(誰用誰知道)
下面介紹下這個小伙伴給編程帶來的快樂:
Validation(數據驗證)
validates_presence_of
validates_inclusion_of
場景(角色表數據約定)
/** * 1:約定角色類型的范圍 * 2:約定角色狀態的范圍 */ public static $validates_inclusion_of = array( array("f_type", "in" => array("role", "group", "department", "member")), array("f_status", "in" => array(1,2)) ); /** * 設定角色名稱、角色狀態、角色類型、角色描述不能為空 */ public static $validates_presence_of = array( array("f_name"), array("f_status"), array("f_type"), array("f_desc") ); //錄入數據不滿足約定條件,就無法保存,再也不用擔心那些臟臟的數據。
Callback(回調)
before_save
before_create
before_update
before_destroy
after_save
after_create
after_update
after_destroy
場景1(角色表操作記錄)
//定義回調函數 public static $before_save = array("setMisc"); //每當角色表保存之前,都默默的把數據格式好,好開心。。。 public function setMisc() { //創建時間,創建人 $this->is_new_record() && ($this->f_create_at = date("Y-m-d H:i:s")); $this->is_new_record() && ($this->f_create_by = $this->op); //更新時間,更新人 $this->f_update_by = $this->op; //操作人 $this->f_update_at = date("Y-m-d H:i:s"); //操作時間 }
場景2(新增資源,推送資源映射表):
//定義回調函數 public static $after_save = array("syncRelations"); //每當資源保存之后,自動把資源數據中的映射字段值,推送給資源映射表。 public function syncRelations() { //獲取資源的映射字段 $mapFiledValue = $this->getMapFiledValue(); $mapFiledValue ? $this->addMap($mapFiledValue) : Map::removeAllByResourceId($this->id); }
場景3(角色刪除):
//定義回調函數 public static $after_destroy = array("deleteRelations"); //每當角色刪除時,自動把系統中角色的成員和角色的資源規則清空,而且是事務的。 public function deleteRelations() { UserRelations::removeAllByRoleId($this->id); RuleRelatinos::removeAllByRoleId($this->id); }
Association(關聯)
has_many
場景(新增角色用戶)
//定義角色表和角色用戶表的關系 public static $has_many = array( array( "relations", "foreign_key" => "f_role_id", "class_name" => "TuniuRbacOrmRoleUser", ) ); //新增角色用戶,默默的把role_id傳遞給了角色用戶表,此處如果用SQL,簡直不忍直視。 Role::first()->create_relation( array( "f_user_id" => $uid ) );
事務(一致性與安全性)
權限系統中數據一致性和數據安全性的重要性是不言而喻,不用事務會被BS的。
在此我們鄭重承諾,權限系統中每一次數據增刪改請求,都是事務處理的。
比如角色保存:
self::transaction( function () use ($params, &$role) { $role->f_name = $params["name"]; $role->f_status = $params["status"]; $role->f_type = $params["type"]; $role->f_desc = $params["desc"]; if ($role->is_invalid()) { throw new Exception("角色相關操作失敗", "900202"); } $role->save(); } );
篇幅有限,這個小伙伴的戰斗力場景遠甚于此。
單元測試(持續交付)坦白的說,用AR是一種編程享受。
一切都如此的完美,沒有測試,又如何可以證明這件事情的完美,又如何可以保障交付的質量。
PHPUnit 是一個輕量級的PHP測試框架。它是在PHP5下面對JUnit3系列版本的完整移植,是xUnit測試框架家族的一員(它們都基于模式先鋒Kent Beck的設計)。
單元測試是一種提高軟件質量非常有效的方法,但很重要的是我們要去實踐和體會。
簡單的介紹下權限管理中的角色行為測試用例:
角色行為測試
數據集(YAML)
t_rbac_user: - f_id: 1 f_name: "zhaoyang2" f_create_at: "2013-10-10 17:04:05" t_rbac_role_user: - f_id: 1 f_user_id: 1 f_role_id: 1 t_rbac_role: - f_id: 1 f_name: "運營研發部-1" f_status: 1, f_type: "department" f_desc: "我們是運營研發部-1" f_create_at: "2013-10-10 17:04:05" f_create_by: "zhaoyang2" f_update_by: "zhaoyang2"
測試代碼:
//預設數據集 public function getDataSet() { return new PHPUnit_Extensions_Database_DataSet_YamlDataSet( fixture("rbac/role.yml") ); } /** * 權限操作-異常驗證 * @expectedException Exception * @expectedExceptionMessage 您無權運營當前數據 */ public function testRoleDeleteException() { Role::first()->remove(); } /** * 權限操作-刪除驗證 */ public function testRoleDelete() { Role::first()->remove("zhaoyang2"); //驗證數據行 $this->assertEquals(1, $this->getConnection()->getRowCount(Role::$table_name)); $this->assertEquals(1, $this->getConnection()->getRowCount(UserRelation::$table_name)); }
鑒權用例和應用管理用例,遠比這個復雜,感興趣的同學可以去 Fork 一把,了解下PHPUNIT的魅力。
結束語PHPUNIT很強大,想合理運用的話,沒有任何捷徑,開始寫測試用例吧。。
其實說架構算上下,就是和大家分享下權限中心的PHP之道。
高效便捷的使用PHP服務我們的工作。
多交流,多分享,書寫更好的PHP代碼,享受編程和技術所帶來的快樂。
RBAC
PHP之道
深入理解PHP內核
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21552.html
摘要:認為權限授權實際上是的問題。具體的權限,正向授權與負向授權。應用建模業務場景權限管理鑒權設計應用建模系統架構上支撐權限系統靈活配置,不僵硬字段,不僵硬行為,基于各種業務權限管控的特征靈活設計。表示許可權與角色之間多對多的指派關系。 序 之前寫過一篇大話權限中心的PHP架構之道,主要是從軟件工程角度介紹,如何通過編碼規范、依賴管理、數據源架構、事務處理、單元測試等技術,來保障權限系統的高...
摘要:認為權限授權實際上是的問題。具體的權限,正向授權與負向授權。應用建模業務場景權限管理鑒權設計應用建模系統架構上支撐權限系統靈活配置,不僵硬字段,不僵硬行為,基于各種業務權限管控的特征靈活設計。表示許可權與角色之間多對多的指派關系。 序 之前寫過一篇大話權限中心的PHP架構之道,主要是從軟件工程角度介紹,如何通過編碼規范、依賴管理、數據源架構、事務處理、單元測試等技術,來保障權限系統的高...
摘要:從年月開始,的開發由作者目前就職贊助。武器一覽無線運營播種機模型動態表單屬性中心標簽系統權限中心模型位置管理一切皆位置回到主題,下面就為大家詳細介紹下,我們如何玩耍。場景包括頁面緩存限速器頁面性能分析狀態統計智能提醒異常線路。 Redis-簡介 Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基于內存亦可持久化的日志型、Key-Value數據庫,并提供多種語言的API。從2...
摘要:的本質是團隊博客,關注互聯網創業技術,每周推薦篇優質文章。堅持爭取做到每周更新,與讀者一起進步。第十一期第十期第九期第八期第七期第六期第五期第四期第三期切換至,第二期發布。創刊,用發布了第一次。 Tuniu Weekly Inspired By 《灣區日報》 我們團隊也想基于這種模式,讓大家感受到技術的人文。 《Tuniu Weekly》就這樣產生了。 《Tuniu Weekly》...
閱讀 2228·2021-11-22 09:34
閱讀 1337·2021-10-11 10:59
閱讀 4435·2021-09-22 15:56
閱讀 3288·2021-09-22 15:08
閱讀 3408·2019-08-30 14:01
閱讀 779·2019-08-30 11:16
閱讀 1133·2019-08-26 13:51
閱讀 2910·2019-08-26 13:43