fix(frontend): call /api/v1/cap and document /api/healthz

Point the login captcha solver at the versioned challenge/redeem endpoints and document the remaining health probe.
This commit is contained in:
ryan
2026-08-30 16:42:33 +08:00
parent 0d53be2896
commit 8931c3559c
4 changed files with 13 additions and 9 deletions
+1 -1
View File
@@ -152,7 +152,7 @@ pnpm dev
|------|------|
| 前端界面 | http://localhost:3000 |
| Swagger 接口文档 | http://localhost:8000/swagger/index.html |
| 健康检查 | http://localhost:8000/api/health |
| 健康检查 | http://localhost:8000/api/healthz |
## ⚙️ 配置说明
+4
View File
@@ -10,6 +10,10 @@ sidebar: false
## [Unreleased]
### 🛠 修复
- 人机验证与健康检查去掉双路径:浏览器只请求 `/api/v1/cap/challenge` 与 `/api/v1/cap/redeem`,探针只保留 `GET /api/healthz`(`{"status":"ok"}`)。旧的 `/api/cap/*`、`/api/health` 与 `/healthz` 不再注册。
### 💄 其他/体验
- 内嵌前端拷贝目标改为 `backend/plugins/drivers/driver_http/dist`,与上游 `//go:embed all:dist` 对齐;发布工作流改为读取 `backend/go.mod`。仓库内 `.gitconfig` 提供 `merge.ours` 驱动,合并上游时保留 OpenFlare 自有路径;Wavelet 的 `build-image.yml` 与 `docker-compose.yml` 已隔离,避免 canary 发布成 wavelet 镜像。
+6 -6
View File
@@ -25,8 +25,8 @@ OpenFlare 的登录端点 `/api/v1/user/login` 缺少用户维度的防护机制
* 在登录页面引入 `cap-widget`(React 19 自定义元素)。
* 提交表单时,伴随提交由 Widget 求解出并得到的 `cap-token`。
2. **Server (控制面后端)**:
* 暴露 `POST /api/cap/challenge` 接口,为客户端分发 PoW 难题和签名的 JWT Token。
* 暴露 `POST /api/cap/redeem` 接口,校验客户端提交的 PoW 解答并核发带有失效时间的登录凭证(Redeem Token)。
* 暴露 `POST /api/v1/cap/challenge` 接口,为客户端分发 PoW 难题和签名的 JWT Token。
* 暴露 `POST /api/v1/cap/redeem` 接口,校验客户端提交的 PoW 解答并核发带有失效时间的登录凭证(Redeem Token)。
* 将 Redeem Token 与对应过期时间保存在内存缓存/Redis 缓存中。
* 在 `POST /api/v1/user/login` 接口中,若启用了验证码保护,先校验并消耗(单次失效)对应的 `cap-token`。
@@ -40,10 +40,10 @@ sequenceDiagram
participant Cache as 内存/Redis 缓存
User->>Browser: 打开登录页面
Browser->>Server: POST /api/cap/challenge (获取难题)
Browser->>Server: POST /api/v1/cap/challenge (获取难题)
Server->>Browser: 返回 {challenge, token, expires} (JWT 格式)
Note over Browser: Widget 在后台(WASM/Worker)执行 PoW 难题计算
Browser->>Server: POST /api/cap/redeem (提交 solutions + token)
Browser->>Server: POST /api/v1/cap/redeem (提交 solutions + token)
alt 校验 PoW 解答通过
Server->>Cache: 存储 Redeem Token (tokenKey:expires)
Server->>Browser: 返回 {success: true, token} (即 cap-token)
@@ -71,7 +71,7 @@ sequenceDiagram
### 3.1 接口定义
#### 1. 获取难题 (GET/POST /api/cap/challenge)
#### 1. 获取难题 (GET/POST /api/v1/cap/challenge)
* **请求方式**:`POST`
* **接口权限**:公开
* **响应负载**(统一 API 信封,`data` 为业务载荷):
@@ -90,7 +90,7 @@ sequenceDiagram
}
```
#### 2. 核销难题 (POST /api/cap/redeem)
#### 2. 核销难题 (POST /api/v1/cap/redeem)
* **请求方式**:`POST`
* **请求负载**:
```json
+2 -2
View File
@@ -135,7 +135,7 @@ function solveInWorker(
export async function getCapToken(scope = 'login'): Promise<string> {
// 1. 获取难题
const challengeRes = await fetch('/api/cap/challenge', {
const challengeRes = await fetch('/api/v1/cap/challenge', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ scope }),
@@ -171,7 +171,7 @@ export async function getCapToken(scope = 'login'): Promise<string> {
console.groupEnd();
// 3. 提交答案兑换一次性凭证
const redeemRes = await fetch('/api/cap/redeem', {
const redeemRes = await fetch('/api/v1/cap/redeem', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: challenge.token, solutions, scope }),