feat(sae): add cloud-gateway adapters and forward mode (0.0.4)

SAE 上这一版只做云网关适配层:/api/taobao/* 字节级透传给 1me.xajuzi.com 上
现有的 H5 后端(旷视调用、评分、报告都留在那边),Java 不再重写测肤逻辑。

- TaobaoEnvelope:客户端要求的 data.ok + data.http_status 信封(HTTP 恒 200)
- TaobaoAuthController:challenge/session/me/logout(native 模式)
- TaobaoSessionService:一次性 challenge + 30 天 Bearer token,按 open_id 限流
  (网关后面所有请求同源 IP,按 IP 计数会变成全站共享 30 次/分钟)
- TaobaoForwardController:mode=forward 时透传,保留原始 query 与 body 字节
  (签名覆盖原始 body,重新序列化会让验签失败)
- TaobaoSignatureVerifier:缺省 sign_method 按 md5 校验
- 打包名固定为 taobao-mvp-backend-0.0.4-forward,SAE 不需要任何环境变量
- pom 版本 0.0.4;mvn test 11/11(新增 8 个用例)
- docs:更新 SAE 操作步骤,新增本次交接文档
This commit is contained in:
xsl
2026-11-01 23:30:35 +08:00
parent 65ba3cc7a5
commit f5c416dd9d
15 changed files with 1021 additions and 8 deletions
+273
View File
@@ -0,0 +1,273 @@
# 交接文档:淘宝小程序 + 聚石塔 SAE + Java MVP
> 日期:2026-11-01 凌晨
> 给下一个 agent:先读「一句话状态」和「明天先做什么」,再按需读后面。
## 一句话状态
**云端链路已经打通**:开放平台服务测试 `POST /api/taobao/ping` 返回:
```json
{
"success": true,
"data": {
"server": "java",
"signMessage": "verify-sign=false, skipped (local/direct mode)",
"appKey": "35486228",
"transport": "gateway",
"ok": true,
"pong": true,
"env": "test",
"signVerified": false
},
"errorCode": null,
"errorMessage": null
}
```
SAE `nnn` 上跑的是 `0.0.2` JAR,SAE 环境变量已清空,JAR 内置 `verify-sign:false`,所以 `signVerified:false` 是**预期**。
**还没做** IDE 真机预览;**签名校验尚未启用**(之前的 `signature mismatch` 未解决,先绕过)。
## 明天先做什么
1. **IDE 真机预览**,验证小程序 → 云网关 → 聚石塔云应用 → 私网 CLB → SAE 整条链路(第 5.1 节)。
2. 真机通过后,再决定是否开签名:重置 35486228 的 AppSecret → 更新 `application-local.yml` → `verify-sign:true` → 打 `0.0.3` 上传(第 5.3 节)。
3. 最后提交这轮未提交的代码(**不要提交 `application-local.yml`**)并 push。
## 当前链路
```text
淘宝小程序(taobao/)
→ @tbmp/mp-cloud-sdk(cloudEnv: test)
→ 淘宝云网关(AppKey 35486228)
→ 聚石塔云应用 1me-net(ID 62829,默认云应用)
→ 私网 CLB lb-k2j324dwux1svaf2akwqx / 192.168.65.185:80
→ SAE 应用 nnn(namespace cn-zhangjiakou:my-namespace)
→ Java Spring Boot 0.0.2,容器 8080
```
## 关键资源 / ID
| 资源 | 值 |
|---|---|
| 开放平台应用(当前正确) | `1me 肌肤状态检测`,AppKey **35486228** |
| 旧应用(不再使用) | `1me肌肤检测`,AppKey 35479221;旧 Secret 不要再用 |
| 聚石塔云应用 | `1me-net`,ID **62829**,默认应用;生产/测试 SLB 都是 `192.168.65.185:80` |
| 聚石塔云应用(未用) | `app-new`,ID 62861;没接 SAE/CLB,别用 |
| SAE 应用 | `nnn`,ID `7c9f2d2a-95d0-4879-afad-323d30f85d30` |
| SAE 命名空间 | `cn-zhangjiakou:my-namespace` |
| VPC | `vpc-8vb5mcvenp8jwa1roqcsa`(`JST_cn-zhangjiakou_vpc-new`) |
| vSwitch | `vsw-8vbna5zb2rq03gaeiymch`(可用区 A) |
| 安全组 | `sg-8vbh8c96h0kotpu7y26r`(“聚石塔官方创建ssh”),需放行 8080 |
| 实例规格 | 1 Core 2 GiB |
| 代码包 | `taobao-mvp-backend-0.0.2.jar`,版本号 `1793466846250` |
| SAE 环境变量 | **已清空**(重要,见“不要做什么”) |
## 已验证 / 未验证
### 已验证
- 后端本地:`mvn test` 4/4(0.0.1 时;版本改 0.0.2 后只 `-DskipTests` 打包,未重跑)。
- 前端:`npm test` 17/17;`taobao/scripts/mvp-local-check.cjs` 本地直连 Java 通过。
- JAR 本地启动:`/actuator/health` UP,`/api/taobao/ping` 正常。
- SAE `nnn` 部署 `0.0.2` 成功,服务测试返回上面的 JSON。
- `signVerified:false` 是预期;`signMessage` 是固定文案,不代表直连;`transport:"gateway"` 证明走了网关。
### 未验证
- IDE **真机预览**(云应用 SDK 模拟器不支持,必须真机)。
- 开启签名后的 `signVerified:true`。
- 真实测肤接口(challenge/session/photo/skin-analyze/analysis/reports/logout)仍在 Node,Java 只有 `ping/whoami/echo`。
## 代码 / 配置状态
### Git
- 已推送:`ac0b7ca feat(sae): add Java MVP backend and Taobao connectivity page`(origin/main 同步)。
- 工作区未提交改动(11 个文件,`git diff --stat`):
- `.gitignore`(忽略 `application-local.yml`)
- `README.md`(交接文档入口)
- `backend-java/README.md`
- `backend-java/pom.xml`(version `0.0.2`)
- `backend-java/src/main/resources/application.yml`(`spring.profiles.active: local`)
- `docs/SAE-Java-MVP-操作步骤.md`(0.0.2 + 4.3.1 更新 JAR)
- `taobao/config.js`(云端 test)
- `taobao/pages/mvp/mvp.js`(显示 cloudType)
- `taobao/pages/splash/splash.js`(云端 test 也显示 MVP 入口)
- `taobao/test/transport.test.cjs`(tower 测试)
- `taobao/utils/transport.js`(tower 模式)
**`application-local.yml` 在 `.gitignore` 里,未跟踪,不要提交。** 它包含 AppSecret;JAR 里也包含,临时方案。
### 后端
- `backend-java/`,Spring Boot 3.5.6 / Java 17。
- `application.yml`:`spring.profiles.active: local`。
- `application-local.yml`:
- `taobao.app-key: "35486228"`
- `taobao.app-secret: <当前 Secret>`
- `taobao.verify-sign: false`
- JAR:`backend-java/target/taobao-mvp-backend-0.0.2.jar`(23.6MB),包含 `BOOT-INF/classes/application-local.yml`。
- 云端已上传该 JAR;SAE 环境变量已清空(否则覆盖 JAR 配置)。
- 接口:`GET/POST /api/taobao/ping`、`POST /api/taobao/whoami`、`POST /api/taobao/echo`、`GET /actuator/health`。
- 签名校验:`TaobaoSignatureVerifier`,算法与 `h5/lib/taobao-auth.js` 一致;`verify-sign:false` 时跳过。
### 前端
- `taobao/config.js` 当前是云端 test:
- `environment: 'development'`
- `transport: 'cloud'`
- `cloudType: 'tower'`
- `cloudEnv: 'test'`
- `cloudAppId: ''`(默认云应用;若 SDK 报默认不存在,填 `62829`)
- `mvpLocal: false`
- `baseUrl: 'https://miniappcloud.taobao.com'`(tower 模式仅占位,不参与请求)
- `assetBase: 'http://127.0.0.1:18180/assets/'`(真机上底图可能加载失败,不影响 MVP 入口)
- `taobao/utils/transport.js`:`cloudType === 'tower'` 时不传 `domain`、不要求 HTTPS、`cloudAppId` 可空;`cloudType === 'empty'` 保持旧行为(空应用/外部服务)。
- `taobao/pages/mvp/mvp`:MVP 页面;`mvpLocal` 时可强制直连 8080,云端时走 transport cloud。
- `taobao/pages/splash/splash.js`:`showMvpDebug = mvpLocal || (transport === 'cloud' && environment !== 'production')`;当前 development+cloud,入口显示。
- `taobao/app.json` 已注册 `pages/mvp/mvp`。
- `taobao/scripts/mvp-local-check.cjs`:本地直连契约测试(独立配置,不依赖 `config.js`)。
- `taobao/test/transport.test.cjs`:17 个测试含 tower 模式。
### 工具 / 环境
- JDK 17:`D:\juzi\tools\jdk17\jdk-17.0.21.0.2+1`
- Maven 3.9.9:`D:\juzi\tools\maven\apache-maven-3.9.9`
- Node 22.23.2:`C:\Program Files\nodejs`
- PowerShell 执行策略 Restricted;先:
```powershell
Set-ExecutionPolicy -Scope Process Bypass
. D:\juzi\tools\env-java.ps1
```
- Taobao IDE 的 `wmic` 兼容 shim:`C:\Users\youmi\.local\bin\wmic.cmd`;重建脚本 `D:\juzi\tools\fix-taobao-ide-wmic.ps1`。IDE 已能打开。
## 5. 明天详细步骤
### 5.1 IDE 真机预览(第一优先级)
1. 确认 IDE 当前小程序是 **35486228**(`1me 肌肤状态检测`),不是 35479221。
2. 重新编译。
3. 点顶部「预览」,手机淘宝扫码(**不要用模拟器**;`cloud.application.httpRequest` 模拟器不支持)。
4. 启动页右上角点「SAE MVP 连通性」。
5. 页面自动调 `/api/taobao/ping`,预期:
- `transport: "gateway"`
- `server: "java"`
- `signVerified: false`(当前 JAR 配置)
- `appKey: "35486228"`
6. 如果成功,MVP 链路验收完成;记录截图。
### 5.2 真机常见错误
| 现象 | 排查 |
|---|---|
| `cloud init failed` | IDE 当前 App 不是 35486228;云应用没设默认;`cloudEnv` 不是 test |
| `cloudAppId` 默认不存在 | `taobao/config.js` 的 `cloudAppId` 填 `62829` |
| `Cannot find module '@tbmp/mp-cloud-sdk'` | `npm.cmd ci`,IDE 里「构建 npm」 |
| 模拟器报 SDK 不支持 | 正常,改用真机预览 |
| `请先配置淘宝云应用和 HTTPS 服务地址` | `cloudType` 不是 tower 或 transport 不是 cloud |
| 真机底图不显示 | `assetBase` 是 127.0.0.1,正常;MVP 入口仍可点 |
| `SIGN_INVALID` | 只会在 `verify-sign:true` 时出现;当前 false,不应出现 |
### 5.3 开签名(真机通过后再做)
1. 开放平台打开 **35486228** 的应用,重置 AppSecret,复制新值。
2. 更新 `backend-java/src/main/resources/application-local.yml`:
- `app-secret: 新值`
- `verify-sign: true`
3. 改 `pom.xml` 版本为 `0.0.3`,重新打包:
```powershell
Set-ExecutionPolicy -Scope Process Bypass
. D:\juzi\tools\env-java.ps1
cd D:\juzi\backend-java
mvn clean -DskipTests package
```
4. 上传 `target\taobao-mvp-backend-0.0.3.jar` 到 SAE `nnn`,部署。
5. 服务测试 `POST /api/taobao/ping`,期望 `appKey:35486228`、`signVerified:true`。
6. 如果仍 `signature mismatch`:
- 确认 SAE 没有残留 `TAOBAO_*` 环境变量(它们会覆盖 JAR);
- 确认 Secret 是 35486228 的当前值,没有空格/换行;
- 点服务测试「请求详情」,核对 `sign_method`、URL query、body;
- 需要时按 `docs/SAE-Java-MVP-操作步骤.md` 第 6 节算法手工复算(仓库里目前没有 `check-gateway-sign.cjs`,之前回答提到过但未创建)。
### 5.4 提交代码
真机通过后:
- 提交这 11 个改动(`pom.xml` 0.0.2、config、transport、splash、mvp、test、docs、两个 README、.gitignore、application.yml),外加本文档 `docs/HANDOFF-2026-11-01.md`。
- **不要** `git add application-local.yml`;它在 `.gitignore` 里。
- push 到 `origin/main`;远端证书已续期(notAfter 2027-01-29),凭据有效。
## 6. 不要做什么 / 已知坑
1. **不要再创建“云托管/新建云应用”**:那是云应用套件,会新建 CPU/容器并要求开通「容器镜像服务个人版」,和现有 SAE `nnn` 不是一回事。用户已提工单确认过。
2. **不要创建聚石塔容器集群/ECS**:入淘引导的「创建集群」是旧经典流程;SAE 不需要。
3. **不要用 `app-new` 62861**:没接 SAE/CLB;用 `1me-net` 62829。
4. **不要用 35479221 的 AppSecret**:当前是 35486228;旧 Secret 不通用。
5. **不要再加 `TAOBAO_VERIFY_SIGN=true` 环境变量**:会覆盖 JAR 的 `verify-sign:false`,回到 `SIGN_INVALID`。要么全删环境变量用 JAR,要么三者都配且 Secret 正确。
6. **不要在模拟器测云应用**:必须真机预览。
7. **不要把 AppSecret 写进小程序代码、git、聊天**:`application-local.yml` 已 gitignore;JAR 里带 Secret 只是临时验证,验证完重置。
8. **主应用其他页面现在不能云测**:Java 只有 ping/whoami/echo;challenge/session/photo/skin-analyze 等还在 Node。只测 MVP 页。
9. **`signMessage:"verify-sign=false..."` 不是直连**:固定文案;看 `transport`。
10. **SAE 应用 `nnn` 的“更多”里没有部署入口时**:用完整 SAE 控制台 `https://saenext.console.aliyun.com/cn-zhangjiakou/app-list/micro`,或应用列表行 `nnn` 的 ⋮;上传走「部署应用 → 代码包部署」。
11. **云托管入淘引导的「关联云应用」灰按钮**:不要按它去创建集群;已经通过「云应用列表 → 关联云应用」关联成功(1me-net 默认)。
12. **`new-new` SAE 应用/自动 VPC**:之前失败的应用,未使用;可删,别拿它当后端。
13. **`application-local.yml` 是临时方案**:正式环境改回环境变量/保密字典,重置 Secret;JAR 不要外发。
## 7. 常用命令
```powershell
# 环境
Set-ExecutionPolicy -Scope Process Bypass
. D:\juzi\tools\env-java.ps1
# 后端构建
cd D:\juzi\backend-java
mvn clean -DskipTests package
# 本地启动
java -jar target\taobao-mvp-backend-0.0.2.jar
# 本地健康/接口
curl.exe http://127.0.0.1:8080/actuator/health
curl.exe -X POST -H "Content-Type: application/json" -d "{}" http://127.0.0.1:8080/api/taobao/ping
# 前端测试
cd D:\juzi\taobao
npm.cmd test
node scripts\mvp-local-check.cjs
```
## 8. 下一阶段(MVP 验收后)
1. 把 `h5/lib/taobao-routes.js` 的接口迁到 Java:
- `POST /api/taobao/challenge`
- `POST /api/taobao/session`
- `POST /api/taobao/me`
- `POST /api/taobao/photo`(64KiB 分片)
- `POST /api/taobao/skin-analyze`(异步任务)
- `POST /api/taobao/analysis`(轮询)
- `POST /api/taobao/reports`
- `POST /api/taobao/logout`
2. 所有 `/api/taobao/**` 统一信封 + 签名;128KB/10s 限制。
3. 账号/历史/图片存 RDS/OSS,不放容器本地盘。
4. 保留 H5 Node 路由不变,Java 只接淘宝;以现有 Node 实现为契约。
5. 接 SLS 日志、Actuator 健康检查、告警,再切正式流量。
## 9. 交接检查清单
- [ ] 真机预览 `transport:"gateway"`、`server:"java"`
- [ ] 记录真机截图/返回
- [ ] 决定是否开签名;若开,重置 Secret、0.0.3、`signVerified:true`
- [ ] 提交 10 个改动,push
- [ ] 清理 `new-new`/`app-new`/旧 35479221(确认无用后)
- [ ] 重置 AppSecret,移除 JAR 内 Secret,改回环境变量/保密字典
- [ ] 开始迁移真实接口
---
**给下一个 agent 的第一句话**:当前服务测试已通过(`transport:"gateway"`、`server:"java"`、`signVerified:false`),先做 IDE 真机预览;不要开签名、不要创建云托管/集群,先读第 6 节“不要做什么”。
+25 -3
View File
@@ -69,7 +69,7 @@ Set-ExecutionPolicy -Scope Process Bypass
. D:\juzi\tools\env-java.ps1
cd D:\juzi\backend-java
mvn -DskipTests package
java -jar target\taobao-mvp-backend-0.0.1-SNAPSHOT.jar
java -jar target\taobao-mvp-backend-0.0.2.jar
```
第一次 `mvn package` 会下载 Spring Boot 依赖,耐心等几分钟。看到类似日志即成功:
@@ -210,7 +210,7 @@ mvn -DskipTests clean package
产物:
```text
D:\juzi\backend-java\target\taobao-mvp-backend-0.0.1-SNAPSHOT.jar
D:\juzi\backend-java\target\taobao-mvp-backend-0.0.2.jar
```
### 4.3 SAE 创建应用
@@ -256,6 +256,28 @@ TAOBAO_VERIFY_SIGN=true
-Xms512m -Xmx1024m -Duser.timezone=Asia/Shanghai
```
### 4.3.1 更新代码包(重新上传 JAR)
应用创建之后,更新 JAR 的入口:
1. SAE 应用 `nnn` → 右上角「部署应用」/「变更」→「代码包部署」→ 上传新 JAR → 确定 → 部署。
2. 如果右上角没有,左侧「变更记录」→「创建变更」→ 代码包部署。
3. 聚石塔资源视图偶尔不显示部署按钮,可直接用完整 SAE 控制台:
```text
https://saenext.console.aliyun.com/cn-zhangjiakou/app-list/micro
```
选 `my-namespace` → `nnn` → 部署应用。
每次上传的 JAR 文件名/版本要不同,SAE 才会当成一个新版本。`pom.xml` 的 `<version>` 已改成 `0.0.2`,产物是:
```text
taobao-mvp-backend-0.0.2.jar
```
SAE 部署页的「版本」可以填 `0.0.2` 或 `20261101-2`。不要重复上传同名同版本的包。
### 4.4 流量接入
- 云应用走**内网私网 SLB**:聚石塔“流量接入”里绑定私网 SLB,后端端口 8080。
@@ -431,7 +453,7 @@ Set-ExecutionPolicy -Scope Process Bypass
# 后端
cd D:\juzi\backend-java
mvn -DskipTests clean package
java -jar target\taobao-mvp-backend-0.0.1-SNAPSHOT.jar
java -jar target\taobao-mvp-backend-0.0.2.jar
# 本地验证
curl.exe http://127.0.0.1:8080/actuator/health