codex/foundry-backend-smoke
造物工坊 · Foundry Core
共享后端的第一版提供 Google 登录。各项目通过同一个 HTTPS API 登录,在私有 PostgreSQL 的认证库中维护独立账号和会话。项目业务库可分别配置独立的数据库和角色。
服务端配置
- 在 Google Cloud 创建一个 Web application OAuth 客户端。授权重定向 URI 填写
https://<API 域名>/auth/google/callback。所有项目信任同一个客户端,因此共享 Google 同意页面的应用名称。 - 在服务器私网准备 PostgreSQL 13 或以上版本。在认证库执行一次
db/001-auth.sql(使用psql -v ON_ERROR_STOP=1),给运行账号授予这四张表所需的查询及增删改权限。 - 按
.env.example注入运行环境变量。每个项目配置一个固定的前端回调地址,本地开发可用 localhost。将 Google 客户端密钥和数据库连接串存入服务器的密钥管理设施。 - 由 Gitea Actions 在
ces-control上使用 Go 1.25 构建并检查。部署工作流仅处理main上影响后端或部署的改动,将二进制启动在服务器 Docker 私网,由 Traefik 提供 HTTPS。通过GET /healthz检查进程,通过GET /readyz检查认证库。 - 代理避免记录 Google 回调的查询参数及认证请求头。设置入口限流,并定时删除三张临时表(
oauth_attempts、login_grants、project_sessions)中expires_at <= now()的记录。
Actions 部署配置
在仓库的 Actions Secrets 配置 GOOGLE_CLIENT_ID 和 GOOGLE_CLIENT_SECRET,在 Actions Variables 配置 FOUNDRY_PROJECTS。变量值为 JSON 对象,例如 {"prompt":"http://localhost:17321/auth/callback"}。部署读取服务器上预先配置的 /opt/endoleap-infra/foundry/database.env,OAuth 值由 Actions 在启动容器时注入。
Google OAuth 的授权回调地址为 https://api.foundry.entroia.com/auth/google/callback。工作流会验证数据库就绪、匿名请求返回 401 和 HTTPS 就绪。前端接入后,可在浏览器用 Google 测试账号验证完整登录、回调、兑换和会话。
前端接入
- 在浏览器用 Web Crypto 生成 32 字节随机值,编码为无填充 Base64URL,作为 verifier 暂存在当前 tab 的 sessionStorage。对 verifier 字符串做 SHA-256 并用相同编码得到 challenge。
- 顶层导航到
GET /projects/<project>/auth/google?challenge=<challenge>。Google 回到共享 API 后,API 将浏览器重定向至已配置的项目回调。 - 回调页从 URL fragment 读取
code或error,用 history.replaceState 清掉 fragment。收到 code 时,向POST /projects/<project>/auth/exchange发送X-Foundry-Code和X-Foundry-Verifier请求头,随后清理暂存的 verifier。code 有效期一分钟,仅可使用一次。 - 将返回的八小时会话凭证保存在内存中,使用
Authorization: Bearer <access_token>调用GET /projects/<project>/auth/me。通过POST /projects/<project>/auth/logout撤销会话并清理本地凭证。刷新页面后,内存凭证需要通过重新登录获取。
同一个 Google 账号首次进入不同项目时,会分别创建用户 ID。会话绑定其签发项目。Google 账号的标识 sub 用于认领同一项目的既有账号,邮箱只作为资料字段。当前注册模式为开放注册。
验收
用同一个 Google 测试账号分别登录两个项目,确认用户 ID 不同。用 A 的会话请求 B 的 me 应返回 401。验证兑换码重放被拒绝,并确认退出 A 后 B 的会话仍有效。
Description
Languages
Go
83.4%
PLpgSQL
7.5%
Shell
7.2%
Python
1.9%