6.1 KiB
6.1 KiB
微信小程序 web-view 壳接入记录
日期:2026-05-03
1. 目标
本次先用微信小程序 web-view 承载现有 H5,不重写 React/Vite 主前端,也不把 SpacetimeDB SDK 或业务规则搬进小程序端。
当前小程序壳只承担四件事:
- 提供微信开发者工具可识别的
miniprogram/工程根目录。 - 在原生小程序壳中调用
wx.login获取小程序code。 - 调用服务器域名下的
/api/auth/wechat/miniprogram-login,由 Rustapi-server兑换微信身份并签发系统登录态。 - 用一个全屏
web-view打开现有 H5 入口,并把系统auth_token放入 H5 现有登录回调 hash。
重要边界:
openid只作为后端微信身份绑定依据,不直接暴露给 H5 当登录凭证。- H5 继续消费本系统 JWT,也就是
#auth_provider=wechat&auth_token=...&auth_binding_status=...。 - 这与
WECHAT_LOGIN_AXUM_IMPLEMENTATION_DESIGN_2026-04-21.md中“微信只提供三方身份,Axum 签发系统 JWT”的边界一致。
2. 文件入口
| 文件 | 说明 |
|---|---|
project.config.json |
指定 miniprogramRoot: "miniprogram/"。 |
miniprogram/app.json |
小程序全局配置,注册 pages/web-view/index。 |
miniprogram/config.js |
业务域名入口配置,需要部署时填写。 |
miniprogram/pages/web-view/index.* |
最小 web-view 页面。 |
server-rs/crates/api-server/src/wechat_auth.rs |
新增小程序登录接口 /api/auth/wechat/miniprogram-login。 |
server-rs/crates/platform-auth/src/lib.rs |
新增 jscode2session 兑换能力。 |
3. 需要手工填写的配置
在 miniprogram/config.js 中填写:
const WEB_VIEW_ENTRY_URL = 'https://你的H5业务域名/';
const API_BASE_URL = 'https://你的服务器域名/';
const MINI_PROGRAM_APP_ID = '你的微信小程序 AppID';
const MINI_PROGRAM_ENV = 'develop';
约束:
- 必须是
https。 - 不能是
localhost或 IP。 WEB_VIEW_ENTRY_URL域名需要在微信小程序后台配置为业务域名。API_BASE_URL域名需要在微信小程序后台配置为 request 合法域名。- H5 页面里的 API、图片、音视频、iframe 等外链也要满足微信侧域名与证书要求。
在 api-server 环境变量中填写:
WECHAT_AUTH_ENABLED=true
WECHAT_AUTH_PROVIDER=real
WECHAT_MINI_PROGRAM_APP_ID="你的微信小程序 AppID"
WECHAT_MINI_PROGRAM_APP_SECRET="你的微信小程序 AppSecret"
如果开放平台网页 OAuth 与小程序使用同一个 AppID/Secret,也可以继续使用已有:
WECHAT_APP_ID="你的微信 AppID"
WECHAT_APP_SECRET="你的微信 AppSecret"
但正式部署建议把小程序配置写到 WECHAT_MINI_PROGRAM_APP_ID 与 WECHAT_MINI_PROGRAM_APP_SECRET,避免和网页 OAuth 配置混淆。
WEB_VIEW_SOURCE_QUERY 默认附加:
clientType=mini_program
clientRuntime=wechat_mini_program
小程序壳调用登录接口时会补传:
x-client-type=mini_program
x-client-runtime=wechat_mini_program
x-client-platform=ios|android|unknown
x-client-instance-id=<小程序本地持久化随机值>
x-mini-program-app-id=<MINI_PROGRAM_APP_ID>
x-mini-program-env=<MINI_PROGRAM_ENV>
这些字段会进入 refresh session 的客户端身份快照;URL query 只作为 H5 识别宿主来源的轻量标记,不作为鉴权依据。
4. 登录链路
当前登录链路固定为:
- 小程序页面启动。
- 调用
wx.login获取一次性code。 - 小程序壳请求:
POST /api/auth/wechat/miniprogram-login
Content-Type: application/json
{
"code": "wx.login 返回的 code"
}
api-server调用微信jscode2session兑换openid/unionid。api-server复用现有微信身份逻辑:- 先按
unionid命中已有身份 - 再按
openid命中已有身份 - 都没有命中时创建
pending_bind_phone的微信壳账号
- 先按
api-server签发系统 access token,并写入 refresh session。- 小程序壳打开:
https://你的H5业务域名/#auth_provider=wechat&auth_token=<系统JWT>&auth_binding_status=active|pending_bind_phone
- H5 复用
consumeAuthCallbackResult()消费auth_token并进入现有登录态恢复流程。
5. 微信后台配置
至少需要在小程序后台配置:
业务域名:承载 H5 的域名。request 合法域名:API_BASE_URL对应的服务器域名。socket 合法域名:若后续小程序原生层直连 WebSocket 才需要;当前不启用。
当前仓库的 H5 仍建议通过同域 /api/* 访问 Rust api-server,避免在小程序和 H5 中分别维护跨域白名单。
6. 当前不做的事
本次不做原生小程序页面迁移,原因是当前主前端依赖:
- React DOM 挂载、浏览器 history 和
window.location。 localStorage/sessionStorage。- 浏览器
fetch与ReadableStreamSSE。 - DOM、Canvas、Three.js 等浏览器渲染能力。
这些能力不能稳定原样运行在原生小程序宿主中。后续如要原生化,应新建小程序端宿主,复用 packages/shared 契约和 api-server BFF,而不是把 src/ 整体搬过去。
本次也不做 openid query 直登。原因是 openid 不是本系统签发的登录凭证,不能表达 token 版本、会话 ID、绑定状态、角色与过期时间,也不能被 H5 直接信任。
7. 验收口径
- 微信开发者工具打开项目根目录后,识别
miniprogram/为小程序源码目录。 - 未填写
WEB_VIEW_ENTRY_URL或API_BASE_URL时,页面显示配置提示,不出现空白页。 - 填写已配置业务域名后,小程序先请求
/api/auth/wechat/miniprogram-login。 - 后端返回
token/bindingStatus/user,并写入 refresh cookie。 - 首页全屏打开 H5,URL hash 中包含
auth_provider=wechat、auth_token、auth_binding_status。 - H5 内
consumeAuthCallbackResult()消费 hash 后,/api/auth/me能返回当前用户。 /api/auth/sessions能看到来源为mini_program / wechat_mini_program的会话记录。