backend/pkg/permission/README.md

9.2 KiB
Raw Blame History

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 模型

# 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 中添加

// 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 強大功能使用

// 🔥 通配符權限 - 一個規則覆蓋所有子路徑
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 權限控制

// 中間件中使用
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)
        }
    }
}

權限初始化

// 初始化基礎權限
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 自動持久化

// 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: "",
  ...
}

索引優化

// 自動創建的索引
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 屬性權限

// 未來可以升級到 ABAC 模型
// 支援基於用戶屬性、資源屬性、環境屬性的權限控制
permissionUC.CheckPermissionWithAttributes(ctx, 
    map[string]interface{}{
        "user.department": "engineering",
        "resource.owner": "john",
        "time.hour": 9,
    })

策略管理 API

// 動態管理策略
policies, err := permissionUC.GetAllPolicies(ctx)
filtered, err := permissionUC.GetFilteredPolicies(ctx, 0, "role_admin")

🎯 遷移優勢

  1. 立即獲得成熟功能 - 通配符、正則表達式、角色繼承
  2. 減少維護成本 - 社群維護,無需自己投入開發時間
  3. 擴展性更強 - 支援複雜的權限模型,適應業務成長
  4. 性能更好 - 內建優化,大量生產環境驗證
  5. 學習成本低 - 豐富的文檔和社群範例

🔧 立即使用

// 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 讓你專注於業務邏輯,而不是重新發明權限輪子。