Files
juzi/docs/微信登录接入与公网部署说明.md

7.8 KiB
Raw Permalink Blame History

微信登录接入与公网部署说明

更新:2026-10-12。当前环境为 Windows 宿主机 + 内网 WSL。

线上状态补充:https://1me.xajuzi.com/state/ 已部署并配置真实微信凭据,服务器检查记录见 线上微信登录部署记录-2026-10-11.md。2026-10-12 用户已确认手机微信登录成功,服务端亦记录成功回调。下文的内网缺配置说明针对本机开发环境。

2026-10-12 白名单复测已通过,基础凭据有效。最新修正和真机验证步骤见微信登录联调记录。已有本机用户可从「我的报告」→「切换登录方式」进入微信登录;微信会话失效不会自动恢复为本机账号,两个账号的报告不自动合并。

本机开发环境限制(不代表线上状态)

本机未配置生产用 WECHAT_APP_ID、WECHAT_APP_SECRET、PUBLIC_BASE_URL。内网 http://192.168.3.25:8080/ 不能作为本次正式授权部署地址。因此本地启用「本机浏览器登录」,不会模拟微信登录成功。线上真实登录已通过,详见联调记录。

官方网页授权适用于具有相应权限的认证服务号等账号;需要在公众号后台配置网页授权域名。普通小程序 AppID、开放平台网站应用 AppID 不能直接替代本方案的服务号 AppID。本实现采用 snsapi_base 获取 OpenID 做账号关联,不请求头像、昵称。

依据:微信官方 H5 网页授权文档(2026-10-10 核对)。实际账号权限和后台配置还需由公众号管理员确认。

已完成的链路

  1. 登录页先勾选现有协议,再选择微信或本机浏览器登录。
  2. 服务端构造授权地址;回调校验一次性 state、浏览器绑定和 10 分钟有效期。
  3. 服务端用 code 换取 OpenID,AppSecret 不发送至前端、不写入报告。
  4. 同一 AppID + OpenID 对应同一个服务端账号,换手机登录后读取该账号最近 5 份报告。
  5. 会话采用 HttpOnly / SameSite=Lax Cookie;公网 HTTPS 配置下附带 Secure。
  6. 未配置微信、未在微信浏览器内打开、授权失败时提供明确提示,可选择本机浏览器登录。

自动化测试使用模拟的微信换码响应,已覆盖 state 缺失、绑定错误、重复回调、子路径回调、同一 OpenID 返回同一账号;这些测试不等同于微信真机验收。

公网服务器配置

部署整个 h5/,包括 lib/、js/report-copy.js、js/report-ui.js、js/account-client.js、js/camera-geometry.js、新版 CSS、图片和字体。需要 Node 18+,建议沿用当前 Node 22。不能仅部署静态文件。

通过服务管理器的私有环境文件设置以下内容,不放入前端,不提交 Git:

HOST=127.0.0.1
PORT=8080
# 仅限 Node 绑定回环、nginx 覆盖 X-Real-IP 的部署方式
TRUST_LOOPBACK_PROXY=1
PUBLIC_BASE_URL=https://你的域名/state/
WECHAT_APP_ID=你的认证服务号AppID
WECHAT_APP_SECRET=你的认证服务号AppSecret
SKIN_API_KEY=你的Face++Key
SKIN_API_SECRET=你的Face++Secret
# 可选:独立持久化目录。未设置则使用 h5/data。
JUZI_DATA_ROOT=/var/lib/juzi-h5

环境文件权限设为仅服务账号可读,systemd 中使用 EnvironmentFile=。重启服务后访问 .../api/auth/config,wechat: true 只代表必需配置齐备,不代表平台授权已经验收通过。

PUBLIC_BASE_URL 必须是用户实际访问的 HTTPS 地址,包含真实子路径。示例回调为:https://你的域名/state/api/auth/wechat/callback。公众号后台填写的是域名,不是完整 URL;按后台要求部署域名验证文件到域名根目录。不要向聊天或代码库粘贴 AppSecret。

反向代理与后台保护

如果使用 /state/ 子路径,反向代理要剥离该前缀。以下片段加入已经配置证书的 HTTPS server 中;实际部署前先核对现有 nginx 配置,不要直接覆盖。

location = /state { return 301 /state/; }

# 管理后台与用户账号接口相互独立;必须继续保护后台。
location ~ ^/state/(admin\.html|css/admin\.css|js/admin\.js|api/admin/.*)$ {
    auth_basic "Juzi Admin";
    auth_basic_user_file /etc/nginx/.htpasswd-juzi;
    rewrite ^/state/(.*)$ /$1 break;
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    client_max_body_size 20m;
    proxy_read_timeout 150s;
}

location /state/ {
    proxy_pass http://127.0.0.1:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    client_max_body_size 20m;
    proxy_read_timeout 150s;
}

根路径部署则设置 PUBLIC_BASE_URL=https://你的域名/ 并相应去掉上述 /state/。不要遗漏 admin.html 和 /api/admin/ 的鉴权,也不要把 Node 8080 直接暴露到公网。现有 Node 管理接口本身不使用新 C 端账号鉴权;公网安全仍依赖后台鉴权和回环监听。

TRUST_LOOPBACK_PROXY=1 用于按真实客户端 IP 限制登录频率;只信任来自回环代理且格式合法的 X-Real-IP。nginx 必须按示例覆盖该头,不能透传浏览器传入值。本地直接访问时不要启用。未启用时按 TCP 对端限流,在反代后会共享同一计数。

当前 WSL 使用 HOST=0.0.0.0 方便局域网测试,局域网内管理接口也可达,请只在可信网络使用。手机 HTTP 访问不是安全相机上下文,会沿用现有系统相机/上传降级;自动实时抓拍需 HTTPS,或在本机 localhost 测试。这与微信授权是否配置是两个不同限制。

数据、迁移与备份

  • h5/data/accounts/identities.json:账号、随机身份凭据的哈希、会话、最近报告索引。
  • h5/data/accounts/reports/<user-id>/<report-id>.json:完整报告快照,含三张照片、检测图层、评分、话术和推荐产品。
  • 原有 data/records.jsonl、data/photos、data/results 继续供后台复核。
  • 本机浏览器 localStorage 只保存随机身份凭据,不再存照片与报告。更换设备/浏览器/站点域名,或清除全部站点数据后,不能靠本机身份找回原账号。
  • 微信与本机账号不自动合并;旧版 localStorage 报告未自动认领迁移,避免错误关联。旧数据不删除。
  • 前台只列出并允许回看最近 5 份,超出 5 份的快照/后台记录暂保留,不代表已物理删除。正式上线需业务方确认保留和删除周期。
  • 迁移时停止写入,备份并迁移完整数据目录,保留访问权限。只同步代码不会带上报告。禁止将数据目录提交 Git 或由 nginx 作为静态目录公开。
  • 当前为单 Node 进程的文件存储,不可对同一目录开多个 worker/多实例;未来扩容需迁移数据库和对象存储。

公网真机验收清单

  • 微信打开 HTTPS 页面,协议可查看、未勾选不能登录。
  • 首次微信登录→首页→三视角检测→我的报告→详情。
  • 同一微信账号换另一台手机,能看到原报告;另一微信账号看不到。
  • 报告七项检测图与初次生成一致,文案、评分、推荐商品不因回看重算。
  • 取消/失败授权后可重新登录或选择本机浏览器登录。
  • 重启服务后报告与账号不丢失。
  • 检查 HTTPS 摄像头权限、三视角自动抓拍、前后镜头、后台鉴权、数据目录不可访问。

协议处理:登录和检测授权复用 h5/index.html 中已有的「Face++ 个人信息与隐私保护政策」(包含儿童相关章节)。本次未发现独立的品牌方用户协议文件,未凭空编写法律条款;正式发布前请业务/法务确认现有政策是否覆盖品牌方的账号关联、报告存储、保存期限和删除渠道。