# Permission 權限管理模組 - Casbin 版 一個基於 **Casbin** 的現代化權限管理模組,完全整合你的專案技術棧,提供強大且靈活的 RBAC 權限控制。 ## 🎯 為什麼選擇 Casbin? 你說得完全對!與其重新發明一個功能精簡的權限系統,**Casbin** 提供了: ### ✅ **社群驗證的成熟解決方案** - 🌟 **6.7k+ GitHub Stars**,經過大量生產環境驗證 - 🔧 **功能完整**:支援 RBAC、ABAC、RESTful、通配符、正則表達式 - 📚 **文檔完善**:豐富的範例和最佳實踐 - 🛠️ **持續維護**:活躍的社群支持和定期更新 ### ✅ **強大的功能特性** - **通配符支援**: `/api/users/*` 一個規則覆蓋所有子路徑 - **正則表達式**: 靈活的權限匹配規則 - **角色繼承**: 複雜的組織架構支援 - **多種模型**: RBAC、ABAC、RESTful 等 - **策略持久化**: 自動保存到你的 MongoDB ## 📁 目錄結構 ``` pkg/permission/ ├── config/ # Casbin 模型配置 │ └── rbac_model.conf # RBAC 權限模型 ├── domain/ # 領域層 │ ├── entity/ # 實體定義 │ ├── repository/ # 倉庫介面 │ ├── usecase/ # 用例介面 (Casbin 增強) │ └── config/ # 配置定義 ├── repository/ # 倉庫實現 │ ├── casbin_adapter.go # Casbin MongoDB 適配器 │ ├── client.go # 客戶端管理 │ ├── role.go # 角色管理 │ └── ... # 其他倉庫 ├── usecase/ # 用例實現 (Casbin API) ├── svc/ # 初始化層 ├── example/ # Casbin 使用範例 └── README.md # 本文件 ``` ## 🚀 核心優勢 ### **🔥 Casbin 強化功能** - **通配符權限**: `GET /api/users/*` 覆蓋所有用戶子路徑 - **正則表達式**: `GET /api/users/\d+` 只允許數字 ID - **角色繼承**: `admin` 繼承 `user` 的所有權限 - **策略分離**: 權限策略與業務邏輯完全分離 - **動態更新**: 運行時動態添加/移除權限,無需重啟 ### **⚡ 技術整合** - **MongoDB 適配器**: 策略自動持久化到你的 MongoDB - **你的錯誤系統**: 完整的 `@errs/` 整合 - **緩存支援**: 使用你現有的 Redis 緩存 - **go-zero 整合**: 無縫整合到你的服務架構 ## 🔧 Casbin 模型 ```ini # pkg/permission/config/rbac_model.conf [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act) ``` 這個模型支援: - **keyMatch2**: 通配符匹配 (`/api/users/*`) - **regexMatch**: 正則表達式匹配 - **角色繼承**: `g(user, role)` 關係 ## 📦 快速整合 ### 1. 在你的 ServiceContext 中添加 ```go // internal/svc/service_context.go import "backend/pkg/permission/svc" type ServiceContext struct { Config config.Config AuthMiddleware rest.Middleware AccountUC usecase.AccountUseCase PermissionUC permission.PermissionUseCase // ← Casbin 增強 AuthUC permission.AuthUseCase RoleUC permission.RoleUseCase Validate vi.Validate } func NewServiceContext(c config.Config) *ServiceContext { rds, err := redis.NewRedis(c.RedisConf) if err != nil { panic(err) } return &ServiceContext{ Config: c, AuthMiddleware: middleware.NewAuthMiddleware().Handle, AccountUC: NewAccountUC(&c, rds), PermissionUC: svc.NewPermissionUC(&c, rds), // ← Casbin 自動初始化 AuthUC: svc.NewAuthUC(&c, rds), RoleUC: svc.NewRoleUC(&c), Validate: vi.MustValidator(), } } ``` ### 2. Casbin 強大功能使用 ```go // 🔥 通配符權限 - 一個規則覆蓋所有子路徑 err = permissionUC.AddPermissionForRole(ctx, "admin", "/api/users/*", ".*") // ✅ 這些都會被允許: // GET /api/users/123 // POST /api/users/123/profile // DELETE /api/users/123/avatar // 🔥 正則表達式權限 - 精確控制 err = permissionUC.AddPermissionForRole(ctx, "viewer", "/api/users/\\d+", "GET") // ✅ 只允許: GET /api/users/123 (數字ID) // ❌ 拒絕: GET /api/users/abc (非數字ID) // 🔥 角色繼承 - 組織架構支援 err = permissionUC.AddRoleForUser(ctx, "john", "admin") err = permissionUC.AddRoleInheritance(ctx, "admin", "user") // john 自動擁有 admin 和 user 的所有權限 // 🔥 動態權限檢查 hasPermission, err := permissionUC.CheckUserPermission(ctx, "john", "GET", "/api/users/123") hasPattern, err := permissionUC.CheckPatternPermission(ctx, "john", "/api/users/456", "DELETE") ``` ## 🎯 實際使用場景 ### **API 權限控制** ```go // 中間件中使用 func PermissionMiddleware(permissionUC permission.PermissionUseCase) rest.Middleware { return func(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID := getUserIDFromJWT(r) // Casbin 自動處理通配符和正則表達式 hasPermission, err := permissionUC.CheckUserPermission( r.Context(), userID, r.Method, r.URL.Path, ) if err != nil || !hasPermission { httpx.WriteJsonCtx(r.Context(), w, 403, types.ErrorResp{ Code: 4030001, Msg: "權限不足", }) return } next(w, r) } } } ``` ### **權限初始化** ```go // 初始化基礎權限 func InitPermissions(ctx context.Context, permissionUC permission.PermissionUseCase) { // 🔥 管理員擁有所有 API 權限 permissionUC.AddPermissionForRole(ctx, "admin", "/api/*", ".*") // 🔥 用戶只能查看和更新自己的資料 permissionUC.AddPermissionForRole(ctx, "user", "/api/users/{{.UserID}}", "GET|PUT") // 🔥 訪客只能查看公開內容 permissionUC.AddPermissionForRole(ctx, "guest", "/api/public/*", "GET") } ``` ## 📊 Casbin 策略儲存 ### **MongoDB 自動持久化** ```javascript // casbin_rules collection { _id: ObjectId, ptype: "p", // 策略類型 v0: "role_admin_001", // 主體 (用戶/角色) v1: "/api/users/*", // 對象 (資源) v2: ".*", // 行為 (動作) v3: "", // 擴展字段 v4: "", // 擴展字段 v5: "" // 擴展字段 } // 角色關係 { ptype: "g", // 分組策略 v0: "user_001", // 用戶 v1: "role_admin_001", // 角色 v2: "", ... } ``` ### **索引優化** ```javascript // 自動創建的索引 db.casbin_rules.createIndex({"ptype": 1}) db.casbin_rules.createIndex({"ptype": 1, "v0": 1}) db.casbin_rules.createIndex({"ptype": 1, "v0": 1, "v1": 1}) ``` ## 🔥 Casbin vs 自建系統 | 功能 | 自建系統 | Casbin | |-----|---------|--------| | **通配符支援** | ❌ 需要自己實現 | ✅ 內建支援 `/api/users/*` | | **正則表達式** | ❌ 需要自己實現 | ✅ 內建支援 `/api/users/\\d+` | | **角色繼承** | ❌ 需要複雜邏輯 | ✅ 自動處理繼承鏈 | | **策略語言** | ❌ 硬編碼邏輯 | ✅ 靈活的 DSL | | **性能優化** | ❌ 需要自己優化 | ✅ 內建緩存和索引 | | **社群支持** | ❌ 需要自己維護 | ✅ 活躍社群,持續更新 | | **文檔和範例** | ❌ 需要自己寫文檔 | ✅ 豐富的官方文檔 | | **測試覆蓋** | ❌ 需要自己測試 | ✅ 大量生產環境驗證 | ## 🚀 進階功能 ### **ABAC 屬性權限** ```go // 未來可以升級到 ABAC 模型 // 支援基於用戶屬性、資源屬性、環境屬性的權限控制 permissionUC.CheckPermissionWithAttributes(ctx, map[string]interface{}{ "user.department": "engineering", "resource.owner": "john", "time.hour": 9, }) ``` ### **策略管理 API** ```go // 動態管理策略 policies, err := permissionUC.GetAllPolicies(ctx) filtered, err := permissionUC.GetFilteredPolicies(ctx, 0, "role_admin") ``` ## 🎯 遷移優勢 1. **立即獲得成熟功能** - 通配符、正則表達式、角色繼承 2. **減少維護成本** - 社群維護,無需自己投入開發時間 3. **擴展性更強** - 支援複雜的權限模型,適應業務成長 4. **性能更好** - 內建優化,大量生產環境驗證 5. **學習成本低** - 豐富的文檔和社群範例 ## 🔧 立即使用 ```go // 1. 初始化 (自動設置 Casbin) PermissionUC: svc.NewPermissionUC(&c, rds), // 2. 添加權限策略 permissionUC.AddPermissionForRole(ctx, "admin", "/api/users/*", ".*") // 3. 分配角色 permissionUC.AddRoleForUser(ctx, "john", "admin") // 4. 檢查權限 (自動處理通配符) hasPermission, err := permissionUC.CheckUserPermission(ctx, "john", "GET", "/api/users/123") ``` 現在你擁有了一個**功能完整、社群驗證、持續維護**的權限系統!🎯 **Casbin** 讓你專注於業務邏輯,而不是重新發明權限輪子。