ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Yao OpenAPI 模式迁移指南:从传统 JWT 平滑升级到 OAuth 2.1 与现代 AI 能力

Yao OpenAPI 模式迁移指南:从传统 JWT 平滑升级到 OAuth 2.1 与现代 AI 能力 Agent 框架后端低代码RAG【免费下载链接】yao✨ All your agents and workspaces in one place, on every device you own. Track tasks on a board, accessible from desktop, mobile, browser, or API. Self-hosted.项目地址https://gitcode.com/gh_mirrors/ya/yao点击查看免费下载本指南面向希望将 Yao 应用从传统模式迁移到OpenAPI 模式的开发者详细讲解如何启用 OpenAPI、更新前端 API 前缀、将 JWT 认证切换为 OAuth 2.1以及利用其带来的 AI Agent、知识库、MCP 协议与 API 热重载能力。读完本文你将掌握一套完整可落地的迁移路径包括配置清单、路由映射、Guard 自动映射、OAuth 端点用法与故障排查方法并能结合仓库源码理解其底层实现原理。OpenAPI 模式概览迁移后你将获得什么当 OpenAPI 模式被启用后应用将自动获得以下能力OAuth 2.1 认证以行业标准的 OAuth 协议替代传统 JWT支持授权码、刷新令牌、设备授权、令牌交换等完整流程AI Agent 集成内置 AI Agent 与聊天能力并支持路径式助手路由/experts/:assistant_id/chat/completions知识库Knowledge Base向量检索与 RAG 支持MCP 协议支持为 AI 工具提供符合 Model Context Protocol 规范的 OAuth 2.1 实现API 热重载修改自定义 API 定义后无需重启服务器即可生效。从源码结构看这些能力并非零散拼装而是由一个统一的 OpenAPI 服务器承载。openapi/openapi.go 中定义的OpenAPI结构持有Config与OAuth两个核心组件其Attach()方法openapi/openapi.go在BaseURL前缀下挂载了/agent、/chat、/kb、/mcp、/llm、/oauth、/user、/file、/job、/setting、/workspace等二十余组系统端点而/api/*下的自定义 API 则由独立的动态路由代理处理详见下文API 热重载一节。快速开始三步完成基础迁移第一步启用 OpenAPI在应用的app.yao中增加 OpenAPI 配置段{ name: My Application, openapi: { enabled: true, baseURL: /v1 } }需要说明的是OpenAPI 服务的完整配置OAuth 签发证书、令牌生命周期、安全策略、客户端默认值等由仓库中的openapi/openapi.yao承载。服务启动时openapi.Load() 会读取并解析该文件配置文件路径为openapi/openapi.yao见 openapi/openapi.go随后创建 OAuth 服务并初始化用户、ACL、OTP 等子系统。仓库的单元测试应用提供了一份带完整字段注释的配置样例unit-test/agent/app/openapi/openapi.yao。其核心字段与默认值整理如下配置段字段说明默认值顶层baseurlOpenAPI 端点统一前缀/v1自动去除尾部斜杠顶层storeOAuth 数据存储Store__yao.oauth.store顶层cacheOAuth 缓存存储__yao.oauth.cache顶层providers.user用户 Provider任意满足字段要求的 Yao 模型__yao.user顶层providers.clientOAuth 客户端 KV 存储__yao.oauth.client基于 Badgeroauthissuer_urlOAuth 令牌签发者 URL必填无oauth.signingsigning_cert_path签名证书路径相对{YAO_ROOT}/openapi/certs/必填无oauth.signingsigning_key_path签名私钥路径相对{YAO_ROOT}/openapi/certs/必填无oauth.signingsigning_algorithm令牌签名算法RS256oauth.signingmtls_enabled是否启用双向 TLSfalseoauth.tokenaccess_token_lifetime访问令牌有效期1hoauth.tokenaccess_token_format访问令牌格式jwt/opaquejwtoauth.tokenrefresh_token_lifetime刷新令牌有效期24hoauth.tokenrefresh_token_rotation是否启用刷新令牌轮换OAuth 2.1 要求falseoauth.tokenauthorization_code_lifetime授权码有效期10moauth.securitypkce_required是否强制 PKCEOAuth 2.1 合规trueoauth.securityrequire_https是否强制 HTTPStrueoauth.securitysecure_cookie是否使用__Host-前缀与Secure标志的 Cookie。HTTP 开发环境访问非 localhost 的局域网 IP如192.168.x.x时需设为falsetrueoauth.securityrate_limit_enabled是否启用限流配rate_limit_requests、rate_limit_windowfalseoauth.clientdefault_client_type默认客户端类型confidential/publicconfidentialoauth.clientdefault_grant_types默认支持的授权类型[authorization_code, refresh_token]oauth.clientdefault_scopes默认 OAuth 作用域[openid, profile, email]oauth.clientdynamic_registration_enabled是否允许动态客户端注册RFC 7591trueoauth.featuresoauth21_enabled启用 OAuth 2.1 特性trueoauth.featuresmcp_compliance_enabled启用 MCP 协议合规false上述默认值大多在 openapi/config.go 与 openapi/config.go 的默认配置逻辑中落实baseurl缺省为/v1cache缺省为__yao.oauth.cachestore缺省为__yao.oauth.storeproviders 缺省为__yao.user与__yao.oauth.client。签发证书的相对路径会被转换为{YAO_ROOT}/openapi/certs/下的绝对路径见 openapi/config.go。第二步更新前端 API 前缀启用 OpenAPI 后API 路径前缀发生变化需要同步更新前端调用传统模式BeforeOpenAPI 模式After/api/user/login/v1/api/user/login/api/product/list/v1/api/product/list推荐做法使用配置变量统一管理 API 前缀避免逐个修改请求// config.js export const API_PREFIX process.env.OPENAPI_ENABLED ? /v1/api : /api; // usage fetch(${API_PREFIX}/user/login, { ... });第三步将 JWT 认证切换为 OAuth用 OAuth 访问令牌access token替换原来的 JWT 令牌// Before: JWT fetch(/api/user/profile, { headers: { Authorization: Bearer jwt-token } }); // After: OAuth fetch(/v1/api/user/profile, { headers: { Authorization: Bearer oauth-access-token } });路由变更从平铺路径到命名空间化路由结构启用 OpenAPI 后所有端点统一挂载在/{baseURL}/前缀之下形成清晰的命名空间/{baseURL}/ ├── api/ # 你的自定义 API隔离命名空间 │ ├── user/ │ ├── product/ │ └── ... ├── __yao/ # 内置 Widgets │ ├── table/ │ ├── form/ │ ├── list/ │ ├── chart/ │ ├── dashboard/ │ └── sui/v1/ ├── oauth/ # OAuth 端点 ├── agent/ # AI Agent ├── chat/ # 聊天会话 ├── kb/ # 知识库 └── ... # 其他系统功能路由映射示例假设baseURL /v1各类型路由的对照关系如下类型传统模式OpenAPI 模式自定义 API/api/user/login/v1/api/user/loginTable Widget/api/__yao/table/pet/search/v1/__yao/table/pet/searchForm Widget/api/__yao/form/pet/find/1/v1/__yao/form/pet/find/1SUI 渲染/api/__yao/sui/v1/render/home/v1/__yao/sui/v1/render/homeOAuth 令牌无/v1/oauth/tokenAI Agent无/v1/agent/chat源码层面的路由挂载这一路由结构的实现位于服务启动逻辑中。service/service.go 中当openapi.Server已初始化时服务会以openapi.Server.Config.BaseURL作为apiRoot用OpenAPIGuards()替换守卫集合注册router.Any(apiRoot/api/*path, DynamicAPIHandler)作为自定义 API 的动态代理调用api.SetRoutes(router, apiRoot, ...)挂载 Widget 路由即__yao前缀下的 table/form/list/chart/dashboard/sui 等调用openapi.Server.Attach(router)挂载全部系统端点。与此同时service/middleware.go 的静态文件中间件会识别BaseURL前缀与/.well-known/发现端点并直接放行确保 OAuth 发现元数据RFC 8414不受静态服务器干扰。认证变更Guard 自动映射API 定义零改动Guard 映射对照表OpenAPI 模式下你现有的 Guard 配置会被自动映射到对应的 OAuth 认证方式Guard 名称传统模式OpenAPI 模式bearer-jwtJWT Bearer TokenOAuth Access Tokenquery-jwtURL 查询串中的 JWTOAuth Access Tokencookie-jwtCookie 中的 JWTOAuth 安全 Cookiecookie-trace会话跟踪OAuth 会话-公开无需认证无需认证这套映射在源码中有明确对应关系。service/guards.go 同时定义了两套守卫Guards传统模式的 JWT 守卫集合bearer-jwt、query-jwt、cookie-jwt、cookie-trace以及cross-origin、widget-table、widget-list、widget-form、widget-chart、widget-dashboardOpenAPIGuards()OpenAPI 模式下的守卫集合。其中bearer-jwt、query-jwt、cookie-jwt、cookie-trace全部指向oauth.OAuth.Guard而cross-origin与各 Widget 守卫保持不变。OpenAPIGuards()被设计为函数而非变量原因正如注释所述——oauth.OAuth是在运行时才初始化的service/guards.go这也解释了为什么服务启动时必须根据openapi.Server的状态选择守卫集合。API 定义文件完全不需要修改例如下面这份 API 定义在两种模式下均有效{ name: User API, version: 1.0.0, guard: bearer-jwt, paths: [ { path: /profile, method: GET, process: scripts.user.Profile } ] }当 OpenAPI 启用时bearer-jwt守卫自动使用 OAuth 认证。这一零改动迁移的关键在于动态代理在分发请求时才解析守卫service/dynamic.go 中DynamicAPIHandler从 API 定义中取出guard交由api.HTTPGuards查表执行该表已在启动时被替换为OpenAPIGuards()的内容。自定义 Guards 继续可用通过进程定义的自定义守卫不受影响{ guard: scripts.auth.CustomGuard, paths: [...] }从 service/dynamic.go 的applyGuard实现可以看到守卫执行时先查内置表api.HTTPGuards未命中则回退到进程守卫api.ProcessGuard(name)自定义守卫因此与内置守卫享受同等优先级。公开 API 两种模式行为一致guard: -的公开 API 在两种模式下无需任何改动{ guard: -, paths: [ { path: /health, method: GET, process: scripts.health.Check } ] }动态代理会直接跳过-守卫service/dynamic.go。OAuth 集成获取、刷新与撤销令牌获取访问令牌授权码流程# Authorization Code Flow curl -X POST /v1/oauth/token \ -d grant_typeauthorization_code \ -d codeauthorization_code \ -d client_idclient_id \ -d redirect_uriredirect_uri \ -d code_verifierpkce_verifier刷新令牌curl -X POST /v1/oauth/token \ -d grant_typerefresh_token \ -d refresh_tokenrefresh_token \ -d client_idclient_id可用的 OAuth 端点端点方法用途/v1/oauth/authorizeGET, POST授权请求/v1/oauth/tokenPOST令牌交换/v1/oauth/revokePOST撤销令牌/v1/oauth/introspectPOST令牌内省/v1/oauth/userinfoGET用户信息/v1/oauth/jwksGETJSON Web Key Set这些端点的注册位于 openapi/oauth.go 的attachOAuth方法中每个端点均标注了对应的 RFC 标准如/authorize对应 RFC 6749 3.1 节、/revoke对应 RFC 7009、/introspect对应 RFC 7662、/jwks对应 RFC 7517、/userinfo对应 OpenID Connect Core 1.0。此外仓库还实现了文档端点表之外的扩展端点端点方法用途标准/v1/oauth/registerPOST动态客户端注册RFC 7591/v1/oauth/register/:client_idGET / PUT / DELETE客户端配置管理RFC 7592/v1/oauth/device_authorizationPOST设备授权流程RFC 8628/v1/oauth/device/authorizePOST授权待处理的设备码RFC 8628/v1/oauth/parPOST推送授权请求RFC 9126/v1/oauth/token_exchangePOST令牌交换RFC 8693令牌端点还支持client_credentials、device_code与 RFC 7523 的 JWT Bearer 断言授权grant_typeurn:ietf:params:oauth:grant-type:jwt-bearer客户端凭证既可走 HTTP Basic Auth 头也可回退到表单参数openapi/oauth.go。OAuth 端点的完整路由映射、MCP 协议特殊要求资源参数校验、规范化资源 URI、state 参数安全、令牌绑定、刷新令牌轮换与安全注意事项参见 openapi/docs/oauth.md。API 热重载修改定义无需重启OpenAPI 模式支持在不重启服务器的情况下热重载自定义 API。触发热重载的三种方式修改apis/*.http.yao文件后可任选以下方式方式一API 调用curl -X POST /v1/api/__reload方式二进程调用Process(yao.api.Reload);方式三自动检测开发模式在开发模式下文件变更会被自动检测并触发 API 重载。底层原理动态路由代理热重载能力的基础是 service/dynamic.go 中的DynamicAPIHandler。该处理器作为/{baseURL}/api/*path的通配路由见 service/service.go接收所有自定义 API 请求后通过api.FindHandler(method, path)在路由表中查找匹配的 API 定义与 handler将路径参数注入gin.Context按路径级守卫优先、API 级守卫兜底的规则应用 Guard执行真正的业务 handler。由于路由表route table在运行时可通过api.ReloadAPIs(apis)重建对应ReloadAPIs()函数见 service/dynamic.go因此 API 定义文件的变化无需重启即可生效。这也是文档中/v1/api/__reload与Process(yao.api.Reload)两条触发路径的共同落点。开发模式的文件监听则由Service.Watch启动service/service.go。可重载与不可重载的内容可热重载不可热重载需重启自定义 API 定义apis/*.http.yaoWidget 定义路由映射OpenAPI 系统路由Guard 配置进程 / 脚本代码另有独立机制处理SUI 前端集成无缝适配 OpenAPISUI 页面可与 OpenAPI 模式无缝协作。后端脚本调用保持不变// pages/home/home.backend.ts import { Process } from yao/runtime; export function getData() { // Process calls remain unchanged return Process(models.user.Find, 1, {}); }后端脚本通过 Process 调用模型与业务逻辑不依赖 HTTP 路由前缀因此无需修改。前端 API 调用使用动态前缀!-- pages/home/home.html -- script // Use the configured API prefix const API_PREFIX window.__yao?.apiPrefix || /api; fetch(${API_PREFIX}/user/profile) .then(res res.json()) .then(data console.log(data)); /script推荐优先读取运行时注入的window.__yao.apiPrefix它天然适配当前部署的baseURL可避免硬编码前缀造成的 404。迁移清单三阶段核对表迁移前备份应用含数据库与openapi/certs/下的证书盘点所有在用 API 端点识别需要更新前缀的前端 API 调用规划 OAuth 客户端注册方案redirect_uri、作用域、授权类型迁移中在app.yao中启用 OpenAPI并完成openapi/openapi.yao配置签发证书、issuer_url、安全策略更新前端 API 前缀配置注册 OAuth 客户端测试完整认证流程授权码 → 令牌 → 受保护 API逐一验证所有 API 端点迁移后移除遗留的 JWT 令牌生成代码更新项目文档对团队开展 OAuth 流程培训监控认证相关异常令牌失效、撤销、限流误伤等故障排查404 Not Found症状启用 OpenAPI 后 API 返回 404。解决方案更新 API 路径以包含新前缀// Wrong fetch(/api/user/profile); // Correct fetch(/v1/api/user/profile);401 Unauthorized症状携带有效 JWT 令牌仍返回 401。解决方案改用 OAuth 访问令牌而非 JWT// Wrong: Using old JWT headers: { Authorization: Bearer jwt-token } // Correct: Using OAuth access token headers: { Authorization: Bearer oauth-access-token }CORS 问题症状前端调用 API 出现 CORS 错误。解决方案确保 OAuth 客户端注册了正确的redirect_uri与来源origin。注意配置中的allowed_redirect_uri_schemes默认[https, http]与allowed_redirect_uri_hosts默认[localhost, 127.0.0.1]会约束可用的回调地址生产环境务必显式配置。热重载不生效症状修改 API 定义后变更未反映到线上。解决方案确认处于开发模式手动触发重载curl -X POST /v1/api/__reload检查 API 定义文件是否存在语法错误路由表构建失败会导致重载静默失败。FAQ可以同时使用 JWT 和 OAuth 吗不可以。启用 OpenAPI 后所有认证统一走 OAuth。JWT 守卫会自动映射到 OAuth仅作为向后兼容手段存在。需要修改 API 定义文件吗不需要。apis/*.http.yao文件保持原样守卫名称会被自动映射到对应的认证方式映射逻辑见 service/guards.go。现有的 JWT 令牌怎么办已签发的 JWT 令牌将不再有效。用户需要使用 OAuth 流程重新认证。启用 OpenAPI 后还能关闭吗可以。在app.yao中删除openapi段或将openapi.enabled设为false即可。但请注意这会同时破坏所有依赖 OAuth 的功能如 OAuth 端点、AI Agent 认证、知识库等。性能会受到多大影响迁移指南中的性能声明为影响可忽略 0.01%动态路由代理每次请求增加约 0.1 微秒。该具体数值目前没有仓库内的基准测试可佐证建议以实测为准。从实现看动态代理的核心开销是一次基于路由表的 handler 查找api.FindHandler见 service/dynamic.go属于常量级操作且该代理仅在 OpenAPI 模式下启用。相关文档OAuth 端点参考openapi/docs/oauth.md完整的 OAuth 2.0/2.1 端点、RFC 标准映射与 MCP 协议要求AI Agent 实现源码openapi/agentAI Agent 端点的具体实现知识库实现源码openapi/kb知识库与 RAG 端点的具体实现OpenAPI 服务器装配openapi/openapi.goOpenAPI 服务器的加载与路由挂载守卫映射service/guards.go传统 JWT 守卫与 OpenAPI OAuth 守卫的完整对照动态路由代理service/dynamic.go热重载与动态分发实现赞分享Agent 框架后端低代码RAG【免费下载链接】yao✨ All your agents and workspaces in one place, on every device you own. Track tasks on a board, accessible from desktop, mobile, browser, or API. Self-hosted.项目地址https://gitcode.com/gh_mirrors/ya/yao点击查看免费下载相关推荐Fragmentation升级实战从传统架构到现代委托模式的平滑迁移Fragmentation升级实战从传统架构到现代委托模式的平滑迁移 你是否曾为Fragment管理中的各种坑而头疼嵌套Fragment难以调试、滑动返移动开发UI组件Fragmentation升级实战指南从传统到现代的平滑迁移方案Fragmentation升级实战指南从传统到现代的平滑迁移方案 还在为Fragment管理混乱、嵌套层次难以调试而烦恼吗 Fragmentation作移动开发UI组件pgsql-http实战5个示例掌握数据库HTTP请求技巧pgsql http实战5个示例掌握数据库HTTP请求技巧 pgsql http是一款强大的PostgreSQL扩展它允许你直接从数据库内部发起HTTP请求后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表