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

98 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 微信 access_token 中控(腾讯云静态 IP 换 token,经 frp 隧道拉取)
## 为什么
gateway 换 access_token 时微信看到的是**本地宽带出网 IP(106.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`
```bash
#!/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"
```
```bash
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,留余量)
```bash
crontab -e
# 加:*/90 * * * * /home/workspace/wxtoken/refresh.sh
```
### 3. 本地 HTTP 服务只绑 127.0.0.1(不出公网,交给 frp
```bash
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(或复用已有)。
```toml
[[proxies]]
name = "wxtoken"
type = "stcp"
secretKey = "换成一串强随机密钥" # 与 132 visitor 一致
localIP = "127.0.0.1"
localPort = 9099
```
## 二、132 侧(frpc 那台)
`frpc.toml` 追加一个 visitor,把腾讯云的 token 服务映射到 132 本地 9099
```toml
[[visitors]]
name = "wxtoken-visitor"
type = "stcp"
serverName = "wxtoken"
secretKey = "换成同一串强随机密钥" # 与腾讯云那串一字不差
bindAddr = "127.0.0.1"
bindPort = 9099
```
reload frpc 后自测(在 132 上):
```bash
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