必须在Caddyfile中显式配置tls { protocols tls1.2 tls1.3; },并确保证书SAN精确匹配小程序域名、链完整、TLS终止点正确,四者缺一不可。

FrankenPHP 服务端必须启用 TLS 1.2+ 且禁用 SSLv3/TLS 1.0/1.1
微信客户端(含小程序基础库)强制要求后端 HTTPS 服务支持 TLS 1.2 或更高版本,FrankenPHP 默认可能沿用系统 OpenSSL 的旧策略。若未显式配置,curl -I https://yourdomain.com 可能返回 SSL routines:tls_process_server_hello:protocol version 类错误,或 Qualys 测评显示 TLS 1.0/1.1 仍启用。
实操建议:
- 检查 FrankenPHP 启动时绑定的
caddyfile或命令行参数,确保未隐式降级;Caddy v2.7+ 默认已禁用 TLS 1.0/1.1,但若你用自定义openssl编译或旧版 Caddy 驱动 FrankenPHP,则需手动加固 - 在
Caddyfile中显式声明 TLS 版本(推荐):https://api.example.com {<br> tls /path/to/cert.pem /path/to/key.pem<br> tls {<br> protocols tls1.2 tls1.3<br> }<br>} - 避免使用系统自带的过期 OpenSSL 库(如 CentOS 7 默认的 1.0.2),FrankenPHP 容器镜像若基于 Debian 12+/Ubuntu 22.04 则更稳妥
证书域名必须与小程序后台「request 合法域名」完全一致
微信不接受通配符、父域名继承或自动重定向匹配。比如你在小程序后台填了 api.example.com,那么 FrankenPHP 响应的证书 Subject Alternative Name(SAN)中必须明确包含该字符串,example.com 或 *.example.com 均无效。
常见踩坑点:
让 AI 读懂微信公众号。自研 7 阶段提取管道,穿透反爬率 99.89%,Token 消耗降低 50%–87%。支持 ChatGPT、Claude、Perplexity、Gemini 等平台无缝引用。
立即学习“PHP免费学习笔记(深入)”;
- Let’s Encrypt 申请时漏掉
-d api.example.com,只加了-d example.com→ 证书无 SAN 条目,微信校验失败 - 使用 Caddy 自动 HTTPS 时,若
Caddyfile中监听的是example.com,但小程序只配了api.example.com,Caddy 会为example.com申请证书,导致域名不匹配 - FrankenPHP 通过反向代理暴露时(如 Nginx → FrankenPHP),务必确认最终 TLS 终止点(即用户直连的那层)所用证书覆盖的是小程序配置的域名,而非内部服务名
证书链必须完整,且根证书被主流操作系统/微信客户端信任
FrankenPHP 本身不处理证书链拼接,它依赖 Caddy 或前置 Web 服务器将证书与中间 CA 证书合并输出。若只部署了站点证书(fullchain.pem 中缺失中间证书),iOS 微信和部分安卓机型会出现 net::ERR_CERT_AUTHORITY_INVALID。
验证方式:
- 用手机微信访问
https://api.example.com,看地址栏是否显示“锁”图标并可点开查看证书路径;若提示“证书不受信任”,大概率是链不全 - 在服务器执行:
openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -noout -text | grep "CA Issuers",确认输出含有效 URI(如http://cacerts.digicert.com/DigiCertTLSRSASHA2562022CA1-1.crt) - 使用
curl --verbose https://api.example.com观察响应头中的subject和issuer是否形成连续链条
FrankenPHP 的 PHP 进程不参与 TLS 握手,但响应头不能破坏 HTTPS 语义
FrankenPHP 是以 SAPI 方式嵌入 Caddy 的,TLS 在 Caddy 层完成,PHP 层看到的是已解密的 HTTP 请求。因此 PHP 代码本身无需特殊适配,但以下两点极易被忽略:
- 不要在 PHP 中硬编码
http://协议生成 URL(如拼接图片地址、跳转链接),应统一用$_SERVER['HTTPS'] === 'on'或$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'判断协议 - 确保响应头不含冲突字段:例如
header('Content-Security-Policy: upgrade-insecure-requests')在 HTTPS 环境下可能引发微信 WebView 异常;又如 PHP 输出 BOM 或调试var_dump导致 JSON 响应开头多出字符,虽不影响 TLS,但会让wx.request解析失败 - 若用 FrankenPHP Worker 模式处理长连接或流式响应,需确认 Caddy 的
timeout和keepalive配置未过早中断连接,否则小程序可能收到net::ERR_CONNECTION_ABORTED
url not in domain list。


















