Files
sundynix-agentix/deploy/wechat-token-zhongkong.md
T
Blizzard cbd0a96ce7 docs(deploy): 微信 token 中控改用 frp stcp 隧道(不上公网,无需域名)
用户腾讯云未配域名、frp 是 toml。改成:腾讯云 token 服务只绑 127.0.0.1,
经 frp stcp(点对点加密隧道)让 132 拉取,token 全程不上公网、不用证书。

- 说明书给出 toml 版 frp 配置(腾讯云 [[proxies]] stcp + 132 [[visitors]])、
  cron 换 token 脚本、切换验证步骤。
- compose:gateway 加 extra_hosts host.docker.internal:host-gateway —— 容器里的
  127.0.0.1 是容器自己,token 落在宿主机 127.0.0.1:9099,须经 host.docker.internal 访问。

代码侧(PullToken + accessToken 中控分支)无改动,沿用上一提交。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 10:02:09 +08:00

4.3 KiB
Raw Blame History

微信 access_token 中控(腾讯云静态 IP 换 token,经 frp 隧道拉取)

为什么

gateway 换 access_token 时微信看到的是本地宽带出网 IP106.58.232.43,动态会变), 一变白名单就失效、二维码建不出来(40164)。微信官方推荐「中控服务器」:一台固定 IP 的机器统一换 token,业务机拉取使用。腾讯云那台(162.14.122.200,静态)当中控。

微信 IP 白名单只限制换 token 这一步(用 appsecret),拿 token 建二维码不查 IP。 所以:腾讯云换 token → gateway 经 frp 隧道拉 token → gateway 本地建二维码。 白名单只填腾讯云 IP,永不失效。

token 全程不上公网:腾讯云 token 服务只绑 127.0.0.1,靠 frp stcp(点对点加密隧道) 让 132 访问。frp 拓扑:腾讯云=frps、132=frpc,均 toml 配置。

一、腾讯云侧(frps 那台)

1. 换 token 脚本 /home/workspace/wxtoken/refresh.sh

#!/bin/bash
APPID="wxc236cddde8e7f863"
SECRET="你的公众号 AppSecret"       # 建议重置后填新的
OUT="/home/workspace/wxtoken/token.json"
resp=$(curl -s "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${SECRET}")
# 只在拿到 access_token 时才覆盖,避免偶发失败把好文件冲掉
echo "$resp" | grep -q '"access_token"' && echo "$resp" > "$OUT.tmp" && mv "$OUT.tmp" "$OUT"
chmod +x /home/workspace/wxtoken/refresh.sh
/home/workspace/wxtoken/refresh.sh          # 手动跑一次,确认 token.json 生成
cat /home/workspace/wxtoken/token.json      # 应有 {"access_token":"...","expires_in":7200}

2. cron 每 90 分钟刷新(token 有效 2h,留余量)

crontab -e
# 加:*/90 * * * * /home/workspace/wxtoken/refresh.sh

3. 本地 HTTP 服务只绑 127.0.0.1(不出公网,交给 frp

cd /home/workspace/wxtoken && nohup python3 -m http.server 9099 --bind 127.0.0.1 >/dev/null 2>&1 &
# 建议做成 systemd 服务常驻,重启不丢

4. 腾讯云 frpc.toml 追加(暴露本地 9099 给隧道)

腾讯云跑着 frps;要把它自己的本地服务经 stcp 暴露,需在该机也跑一个 frpc(或复用已有)。

[[proxies]]
name = "wxtoken"
type = "stcp"
secretKey = "换成一串强随机密钥"        # 与 132 visitor 一致
localIP = "127.0.0.1"
localPort = 9099

二、132 侧(frpc 那台)

frpc.toml 追加一个 visitor,把腾讯云的 token 服务映射到 132 本地 9099

[[visitors]]
name = "wxtoken-visitor"
type = "stcp"
serverName = "wxtoken"
secretKey = "换成同一串强随机密钥"      # 与腾讯云那串一字不差
bindAddr = "127.0.0.1"
bindPort = 9099

reload frpc 后自测(在 132 上):

curl -s http://127.0.0.1:9099/token.json   # 应返回腾讯云那份 token

三、gateway132 的 .env

# 容器里的 127.0.0.1 是容器自己,须用 host.docker.internal 指到宿主机
WECHAT_TOKEN_URL=http://host.docker.internal:9099/token.json
WECHAT_TOKEN_SECRET=
  • compose 已加 extra_hosts: host.docker.internal:host-gateway(容器可达宿主机端口)。
  • 密钥留空即可:stcp 的 secretKey 已是网络层鉴权,token 不上公网。
  • 配了 gateway 就只从中控拉、不自己换 token;不配则维持直连。

四、切换 + 验证(关键,坐实 qrcode 不受 IP 限制)

  1. 先让本地 IP 和腾讯云 IP 都在白名单,配好上面一切、部署,扫码确认能登录。
  2. 去公众平台把本地 IP 从白名单删掉,只留腾讯云 162.14.122.200,再扫码:
    • 能登录 → 换 token 走了中控、建二维码本地也没被拦,方案坐实、IP 隐患彻底消除。
    • 建二维码报 40164 → qrcode 也受 IP 限制,改用备选:腾讯云装 tinyproxy 正向代理, gateway 加 WECHAT_HTTP_PROXY(需再改一处 http 客户端)。

排查

  • gateway 日志 [wxlogin] 建二维码失败: ... 40164 → 中控没生效或没配 env,仍在本地换 token
  • 132 上 curl 127.0.0.1:9099/token.json 不通 → frp stcp 没打通(检查两端 secretKey 一致、frpc 都 reload 了)
  • token.json 过期/为空 → cron 没跑或 refresh.sh 手动生成失败
  • 容器内拉不到(宿主机能拉到)→ compose 的 extra_hosts 没生效,或用了 127.0.0.1 而非 host.docker.internal