mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-28 05:46:36 +08:00
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:
+1
-1
@@ -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 |
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
|
||||
@@ -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 镜像。
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }),
|
||||
|
||||
Reference in New Issue
Block a user