动态

详情 返回 返回

PHP-Casbin:一個讓開發者不再為權限控制 “重複造輪子” 的工具 - 动态 详情

今天想和大家聊聊這個陪伴我從 “個人側寫” 到 “企業級解決方案” 的開源項目,一個讓 PHP 開發者不用再為權限控制 “重複造輪子” 的工具。

從 2018 年發佈第一個版本,到現在 GitHub 1.3k + Star,PHP-Casbin的成長,其實是無數 PHP 開發者 “權限痛點” 的解決方案集合。

如果你也曾在項目裏寫過if($role == 'admin')的硬編碼,或是為多租户權限隔離撓破頭,那這篇文章,或許能給你一個更優雅的答案。

那些踩過的致命權限坑

曾經接手過一個電商 SaaS 項目的權限重構。當時的代碼讓我至今印象深刻:100 多個控制器裏,每個方法都嵌着權限判斷邏輯,比如訂單列表頁要寫“管理員看所有、商家看自己的、客服看分配的”,光是這一段邏輯,在不同模塊裏重複了 20 多次。

更致命的是,業務迭代中暴露的許多問題:

1. 硬編碼邏輯:改一個權限,牽出 10 個 bug

當時項目裏的權限判斷全是if-else嵌套,比如:

// 訂單列表權限判斷(項目代碼片段)
if ($user->role == 'admin') {
    // 管理員查所有
    $orders = Order::all();
} elseif (\$user->role == 'merchant') {
    // 商家查自己的
    $orders = Order::where('merchant_id', $user->merchant_id)->get();
} elseif ($user->role == 'customer_service') {
    // 客服查分配的
    $orders = Order::where('cs_id', $user->id)->get();
}

當業務新增 “運營角色能看所有商家的未付款訂單” 時,不得不在多個相關方法里加判斷,如果漏改了幾個,上線後直接導致運營看不到數據,這種 “牽一髮動全身” 的痛,相信很多開發者都懂。

2. 權限模型單一:多場景需求無法滿足

電商項目裏,除了 “誰能看訂單” 的RBAC需求,還有 “用户只能改自己的資料”(ACL)、“VIP 用户能訪問會員接口”(屬性權限)、“API 接口按 HTTP 方法控制”(RESTful)。

但當時的架構只能支持RBAC,為了實現其他需求,只能寫額外的 “補丁代碼”,最後權限邏輯亂成一團。

3. 無動態權限:臨時授權要改代碼

如果業務方緊急需求:“讓某商家臨時查看另一個商家的訂單,只看 3 天”。

但現有架構裏,要麼給商家加 “管理員角色”(風險大),要麼改代碼加特殊判斷(週期長),最後只能用臨時表曲線解決, 這種“動態權限”的缺失,讓系統靈活性大打折扣。

4. 多框架難兼容:換項目要重寫權限

當時同時維護Laravelgin+gorm兩個框架的項目,權限邏輯只能分開寫兩套。也沒有一個公共維護權限的中間層,不用框架、不同語言的項目各自維護各自的項目權限。

正是這些痛點,才想尋求找一個:輕量、靈活、跨框架跨語言的權限框架,讓開發者不用再為權限邏輯消耗精力

那就是Casbin,其核心思想是策略與模型分離,並且支持多種編程語言及主流框架的快速集成,為開發者提供了覆蓋ACLRBACABAC等數十種模型的靈活權限控制方案,企業可在混合技術棧中維護統一的權限體系,降低多系統協同成本。

PHP-Casbin 核心能力

經過 6 年迭代,PHP-Casbin 已經從 “簡單的 RBAC 工具”,成長為覆蓋 99% 權限場景的企業級框架。它的核心價值,都圍繞 “讓權限控制更簡單” 展開:

1. 支持多種主流權限模型,一套框架搞定所有場景

不用再為不同業務寫不同權限邏輯!PHP-Casbin 內置多種模型,你只需改配置文件就能切換:

模型類型 適用場景 示例需求
ACL 簡單的用户 - 資源授權 “用户 A 能編輯文章 1”
RBAC 多角色權限管理 “管理員能看所有訂單,商家只能看自己的”
RBAC with Domains 多租户 / 多域名隔離 “租户 A 的管理員不能操作租户 B 的數據”
ABAC 基於屬性的動態權限 “用户只能查看自己創建的、未過期的訂單”
RESTful API 接口權限控制 “GET /api/orders 允許,POST /api/orders 僅管理員允許”

比如要實現 “多租户 RBAC”,只需在模型文件(model.conf)里加一行配置:

[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act

[role_definition]
g = _, _, _ # 第三個參數表示domain(租户)

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act

然後在策略裏定義 “租户 A 的 admin 角色能訪問租户 A 的訂單”:

p, admin, tenantA, /order, read  # 角色admin在tenantA下能讀/order
g, alice, admin, tenantA         # 用户alice是tenantA的admin

這樣一來,alice 只能訪問 tenantA 的訂單,完全隔離其他租户數據,不用寫一行業務代碼,全靠配置策略實現。

2. 輕量無侵入,3 步集成到任意項目

很多開發者擔心 “引入權限框架會增加項目複雜度”,但 Casbin 從設計之初就堅持 “最小侵入”:

PHP-Casbin為例,其核心包僅 300KB,無冗餘依賴,通過Composer安裝時,除了核心代碼,不會引入過多其他庫,避免給項目 “增重”:

composer require casbin/casbin

PHP-Casbin支持幾乎所有主流PHP框架的快速集成,不管你用LaravelThinkPHPYii2WebmanHyperfEasySwoole等,還是原生 PHP,都能無縫集成。以Laravel為例,只需 3 步:

# 1. 安裝適配包
composer require casbin/laravel-authz

# 2. 發佈配置文件,執行sql遷移
php artisan vendor:publish
php artisan migrate

# 3. 執行權限決策
// to check if a user has permission
if (Enforcer::enforce("eve", "articles", "edit")) {
    // permit eve to edit articles
} else {
    // deny the request, show an error
}

不同框架模型和策略配置邏輯完全一致,換框架不用重新學權限邏輯。它的策略支持多種存儲方式:策略規則想存在哪就存在哪。權限策略(誰能訪問什麼資源)可以存在文件、MySQL、Redis、MongoDB 等地方,切換時只需改配置。

3. 動態權限管理:不用改代碼,實時調整權限

業務方經常需要 “臨時給某個用户開權限”,PHP-Casbin 提供了完整的 API 來動態操作權限:

// 給用户bob添加“讀/order”權限
$enforcer->addPolicy('bob', '/order', 'read');

// 給用户bob添加admin角色
$enforcer->addRoleForUser('bob', 'admin');

// 禁止用户bob訪問/order
$enforcer->addPolicy('bob', '/order', 'read', 'deny');  // 支持allow/deny

// 批量刪除權限
$enforcer->removePolicies([['bob', '/order', 'read']]);

這些 API 可以集成到你的 “權限管理後台”,讓運營或管理員自己調整權限,不用開發介入。

4. 性能優化:支持緩存和批量檢查

當項目用户量達 10 萬 + 時,權限檢查的性能很關鍵 PHP-Casbin 做了兩點優化:

  • 規則緩存:把常用的權限規則緩存到 Redis,避免每次檢查都查數據庫;
  • 批量檢查:一次檢查多個權限,減少 IO 次數:

場景案例

PHP-Casbin 可以用於電商、SaaS、政企等領域的企業級應用,這裏分享幾個典型案例,看看它在實際項目中如何發揮價值:

案例 1:電商平台 —— 多角色權限隔離

某知名電商平台(日活 50 萬 +)用 php-casbin 實現了 “平台管理員 - 商家 - 客服 - 買家” 的四層權限體系:

  • 平台管理員:能查看所有商家數據、配置全局規則;
  • 商家:只能操作自己店鋪的商品、訂單,看不到其他商家數據;
  • 客服:只能處理分配給自己的售後工單,不能修改商品價格;
  • 買家:只能查看自己的訂單、修改個人信息。

案例中的核心問題是 “商家數據隔離”,通過 “RBAC with Domains” 模型,把每個商家作為一個 “domain”,權限規則綁定到 domain 上,徹底解決了 “商家越權查看數據” 的問題。

案例 2:SaaS 服務 ——API 接口權限控制

某 SaaS 服務商(服務 1000 + 企業客户)用 php-casbin 管理旗下 200 + 個 API 接口的權限:

  • 給不同套餐的客户分配不同接口權限(基礎版能調用用户接口,企業版能調用數據分析接口);
  • 結合 JWT 令牌,在網關層自動校驗每個 API 請求的權限;
  • 客户升級套餐時,通過 API 自動開放更多接口權限,不用人工操作。

如果用 “接口白名單” 的方式管理權限,每次新增接口都要改配置。用 php-casbin 後,接口權限通過策略規則管理,新增接口只需加一條規則,而且支持 “按接口前綴控制”(比如/api/v1/*)。

案例 3:政企系統 —— 動態權限與審計

某政務系統(涉及敏感數據)用 php-casbin 實現了 “基於角色 + 屬性” 的權限控制:

  • 基礎權限用 RBAC(比如 “科室管理員能看本科室數據”);
  • 動態權限用 ABAC(比如 “只有工作日 9:00-18:00 能修改數據”);
  • 所有權限操作都記錄審計日誌,滿足等保要求。

傳統的權限系統無法支持 “時間限制”,只能通過定時任務開關權限。用 php-casbin 的 ABAC 模型後,只需在匹配器里加時間判斷:

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act && r.now >= "09:00" && r.now <= "18:00"

然後在檢查權限時傳入當前時間:

$enforcer->enforce('user1', '/data', 'edit', ['now' => date('H:i')]);

這樣就實現了 “僅工作時間能修改數據”,不用寫任何定時任務。

寫在最後

當微服務架構與雲原生成為技術新常態,傳統權限模型可能面臨模型僵化、擴展困難、多語言協同繁瑣等問題。

而PHP-Casbin作為Casbin生態的 PHP 實現,通過統一的模型設計,為開發者提供了覆蓋 ACL、RBAC、ABAC 等數十種模型的靈活權限控制方案,使用 Casbin 來做權限控制是一種跨平台、動態策略的現代化解決方案。

user avatar tpwonline 头像 yujiaao 头像 lenglengdechaomian 头像 josie_68d213f999ae8 头像 zero_dev 头像 yuhuashi_584a46acea21f 头像 cryptorzz 头像 yanwushu 头像 selectdb 头像 reddish 头像 zhishuangdemaipian 头像 shiwangdehongshu 头像
点赞 17 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.