From d043e7366ff63084d41bca69e8dbb264cb63530b Mon Sep 17 00:00:00 2001 From: ryan Date: Sat, 29 Aug 2026 11:40:50 +0800 Subject: [PATCH] docs: update developer guide and white paper with router whitelist and session fallback --- docs/WAVELET_DEVELOPER_GUIDE.md | 22 +++++++++++++++------- docs/WAVELET_WHITE_PAPER.md | 13 +++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/docs/WAVELET_DEVELOPER_GUIDE.md b/docs/WAVELET_DEVELOPER_GUIDE.md index 400348b8..29c0b694 100644 --- a/docs/WAVELET_DEVELOPER_GUIDE.md +++ b/docs/WAVELET_DEVELOPER_GUIDE.md @@ -114,25 +114,33 @@ func (s *AuthServiceImpl) OnLoginSuccess(c context.Context, uid string) { --- -### 场景 4:如何开发并注册一个 HTTP API 接口?如何添加路由中间件? -插件通过 `ctx.Router()` 声明路由。微内核支持标准 Gin 路由组与中间件挂载: +### 场景 4:如何开发并注册一个 HTTP API 接口?如何添加路由中间件与白名单? +插件通过 `ctx.Router()` 声明路由。微内核支持标准 Gin 路由组、中间件挂载与免鉴权白名单机制: ```go func (p *OrderPlugin) Apply(ctx *core.Context) error { - // 获取全局或 auth 插件提供的中间件 + // 1. 如果插件包含无需登录的公开接口,主动注册到 Router 白名单(支持精确路径与通配符如 /api/v1/public/*) + ctx.Router().RegisterWhitelist( + "/api/v1/orders/public-status", + "/api/v1/orders/callback/*", + ) + + // 2. 获取全局或 auth 插件提供的鉴权中间件 authSvc, _ := core.Inject[contracts.AuthService](ctx) - // 创建带版本前缀和鉴权中间件的路由组 + // 3. 创建带版本前缀和鉴权中间件的路由组 group := ctx.Router().Group("/api/v1/orders", authSvc.RequireAuthMiddleware()) - // 注册 Handler - group.GET("", p.handleListOrders) + // 4. 注册 Handler + group.GET("/public-status", p.handlePublicStatus) // 命中白名单,自动免鉴权放行 + group.GET("", p.handleListOrders) // 受保护接口,需登录鉴权 group.POST("", p.handleCreateOrder) group.GET("/:id", p.handleGetOrderDetail) return nil } ``` +> 💡 **鉴权放行防线**:`auth` 插件提供的 `RequireAuthMiddleware()` 内部已接入白名单拦截器。所有注册到白名单的路由在经过鉴权中间件时均会自动放行,彻底杜绝免鉴权接口被全局或组级鉴权中间件误拦截(返回 401 Unauthorized)。 --- @@ -622,7 +630,7 @@ Wavelet/ | 扩展点/能力方法 | 返回类型 | 功能说明 | 适用场景 | | :--- | :--- | :--- | :--- | -| `ctx.Router()` | `RouterExtension` | 声明 HTTP 路由、前缀分组与挂载中间件,支持 `Unregister` / `UnregisterByID` | 暴露 API 接口、Web 控制台 | +| `ctx.Router()` | `RouterExtension` | 声明 HTTP 路由、前缀分组、挂载中间件与免鉴权白名单注册(`RegisterWhitelist`, `IsWhitelisted`),支持 `Unregister` / `UnregisterByID` | 暴露 API 接口、公开免鉴权端点、Web 控制台 | | `ctx.Task()` | `TaskExtension` | 注册 Asynq 异步任务消费处理器,支持 `Unregister` | 耗时后台任务、异步消息发送 | | `ctx.Schedule()` | `ScheduleExtension`| 注册 Cron 定时调度任务,支持 `Unregister` | 定时报表统计、周期性清理 | | `ctx.Migrations()` | `MigrationExtension`| 注册插件专属的 Goose SQL 迁移嵌入系统,支持 `Unregister` | 自建数据表、版本升级 | diff --git a/docs/WAVELET_WHITE_PAPER.md b/docs/WAVELET_WHITE_PAPER.md index 2c66ad38..ff1193a9 100644 --- a/docs/WAVELET_WHITE_PAPER.md +++ b/docs/WAVELET_WHITE_PAPER.md @@ -182,5 +182,18 @@ Wavelet 贯彻了 Cordis 核心范式,通过形式化保证解决组件系统 - 当 `redis.enabled = true`:`cache`、`driver_asynq_worker` 与 `driver_asynq_cron` 自动激活,无缝升级为分布式高可用架构。 - **动态拔插可组合性**:所有互斥插件可同时通过 `app.Use(...)` 注册,装配根无需编写侵入式的 `if-else` 条件分支,全面实现架构的时空可组合性与高内聚。 +--- +## 7. HTTP 驱动白名单机制与自包含认证防线 (HTTP Driver Whitelist & Auth Defense) +### 7.1 微内核路由白名单机制 (Router Whitelist Extension) +在插件化中台架构中,鉴权中间件若以全局或组级形式挂载,极易导致免鉴权公开接口(如登录、注册、OAuth 回调、人机验证)被误拦截并返回 `401 Unauthorized`。Wavelet 在微内核扩展点(`extpoints.RouterExtension`)中内建了声明式白名单机制: +- **声明式注册**:插件通过 `ctx.Router().RegisterWhitelist(patterns...)` 主动注册免鉴权路由,支持精确路径与通配符(如 `/api/v1/oauth/*`、`/api/v1/oauth/:source/authorize`)。 +- **作用域支持**:路由组(`RouterGroup`)支持相对路径白名单注册,自动与父级路由前缀级联。 + +### 7.2 认证域所有权主动声明与鉴权前置放行 +- **所有权主动声明**:认证域(`auth` 插件)与业务插件在 `Apply` 中主动注册其管辖的公开/免鉴权接口(如 `/api/v1/user/login`、`/api/v1/user/register`、`/api/v1/oauth/callback`、`/api/v1/cap/challenge` 等)。 +- **前置放行防线**:`auth` 提供的登录鉴权中间件(`LoginRequired`)在执行 Token/Session 校验前,必须优先匹配白名单并直接放行,彻底消除公开接口误拦截。 + +### 7.3 Session 存储双模与自动降级保障 +- **零 Redis 平滑回退**:`driver_http` 运行时驱动适配 `redis.enabled` 配置。当 Redis 处于禁用状态或连接不可用时,自动降级为基于安全加密的 `cookie.NewStore`,确保全套基础中间件(Recovery、CORS、Session、Tracing、Logger)永不脱落,登录与注册会话下发 100% 稳定可靠。