You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/doc/integration.md

4.1 KiB

VBase 集成指南

1. 引入路由

import "github.com/veypi/vbase/api"

func main() {
    // 挂载 vbase 路由到 /api/vb
    rootRouter.Extend("/api/vb", api.Router)
}

2. 配置权限中间件

import "github.com/veypi/vbase/api/middleware"

// 全局启用路由权限检查(推荐)
router.Use(middleware.Perm("your-domain"))

// 未配置的接口默认拒绝
// 无权限时返回 X-Required-URL 响应头

3. 注册路由权限

3.1 自动注册(推荐)

// 启动时自动扫描并注册所有路由
middleware.InitVBaseRoutePolicies()

// 首次启动后,在数据库中修改权限配置即可

3.2 手动注册

// 公开接口
middleware.RegisterRoutePolicy("myapp", "/api", "/public", "GET", "public", "read", true)

// 需要权限的接口
middleware.RegisterRoutePolicy("myapp", "/api", "/users", "GET", "user", "list", false)
middleware.RegisterRoutePolicy("myapp", "/api", "/users/{id}", "PATCH", "user", "update", false)

// 重新加载缓存
middleware.ReloadRoutePolicies()

4. 数据库配置权限

4.1 路由权限表 (route_policies)

字段 说明 示例
domain 领域标识 "myapp"
prefix 路由前缀 "/api"
pattern 路由模式 "/users/{id}"
method HTTP方法 "GET"
resource 资源类型 "user"
action 操作类型 "read"
effect 效果 "allow"/"deny"
condition 条件 "owner"/"admin"
required_url 申请地址 "/apply-perm?r=user&a=read"
is_public 是否公开 true/false

4.2 用户权限表 (policies)

-- 用户拥有 user:read 权限
INSERT INTO policies (code, resource, action, effect)
VALUES ('user-read', 'user', 'read', 'allow');

-- 关联到角色
INSERT INTO roles (code, name, policy_ids)
VALUES ('viewer', '查看者', 'policy-id-1,policy-id-2');

5. 在 Handler 中设置资源所有者

func getUser(x *vigo.X, req *GetUserReq) (*User, error) {
    user := queryUser(req.ID)

    // 设置所有者到上下文,用于 condition=owner 检查
    x.Set("owner_id", user.ID)

    return user, nil
}

6. 完整示例

package main

import (
    "github.com/veypi/vbase/api"
    "github.com/veypi/vbase/api/middleware"
    "github.com/veypi/vigo"
)

func main() {
    r := vigo.NewRouter()

    // 1. 挂载 vbase
    r.Extend("/api/vb", api.Router)

    // 2. 业务路由
    api := r.SubRouter("/api/v1")

    // 3. 启用权限检查
    api.Use(middleware.AuthRequired())
    api.Use(middleware.OrgContext())
    api.Use(middleware.Perm("myapp"))

    // 4. 注册权限(只需一次,后续在数据库中配置)
    middleware.RegisterRoutePolicy("myapp", "/api/v1", "/projects", "GET", "project", "list", false)
    middleware.RegisterRoutePolicy("myapp", "/api/v1", "/projects", "POST", "project", "create", false)
    middleware.RegisterRoutePolicy("myapp", "/api/v1", "/projects/{id}", "GET", "project", "read", false)
    middleware.RegisterRoutePolicy("myapp", "/api/v1", "/projects/{id}", "PATCH", "project", "update", false)
    middleware.RegisterRoutePolicy("myapp", "/api/v1", "/projects/{id}", "DELETE", "project", "delete", false)

    // 5. 无需在 handler 中加权限代码
    api.Get("/projects", "项目列表", listProjects)
    api.Post("/projects", "创建项目", createProject)
    api.Get("/projects/{id}", "项目详情", getProject)
    api.Patch("/projects/{id}", "更新项目", updateProject)
    api.Delete("/projects/{id}", "删除项目", deleteProject)

    vigo.Run(r)
}

7. 权限检查流程

请求 → AuthRequired(认证) → OrgContext(组织) → Perm(权限检查) → Handler
                              ↓
                    查找 route_policies
                              ↓
                    匹配 domain + method + path
                              ↓
                    检查 resource:action 权限
                              ↓
                    无权限 → 返回 X-Required-URL

8. 配置热更新

// 修改数据库后,调用 API 刷新缓存
middleware.ReloadRoutePolicies()

无需重启服务,权限配置实时生效。