追梦学习库

追梦站点修复全过程记录

35 阅读
文章摘要

zhuimeng.vip QQ登录302、Cloudflare根域跳www、zmxxk.cn前台登录弹窗刷HTML等修复全过程记录。

追梦站点修复全过程记录(2026-10-19~10-20,Asia/Shanghai)

一、问题清单与结果

# 问题 结果
1 zhuimeng.vip QQ 登录空白页、不跳 QQ 互联 ✅ 已修复,线上返回 HTTP 302
2 根域 zmxxk.cn / zhuimeng.vip / nanke.work 不跳 www ✅ 已修复,线上返回 HTTP 301 → www
3 zhuimeng.vip 是否串到南柯站 ✅ 已核对:追梦与南柯内容分离正常
4 zmxxk.cn 前台登录弹窗刷出后台 HTML 源码 / 登录异常 ✅ 已修复:loginauth.php + wind-max/footer.php;用户确认「好像是可以了」
5 首页仍出现不带 www 的导航链接 ⚠️ 后台导航表已是 www;前台偶发裸域多半来自模板/缓存,可清缓存后再查

二、QQ 登录(zhuimeng.vip)

现象

  • 链接:https://www.zhuimeng.vip/oauth/qq?action=login&rurl=...
  • 浏览器停在空白页,不进入 QQ 互联
  • curl -sSI 见:HTTP/2 200 + Location: https://graph.qq.com/oauth2.0/authorize?...
  • 浏览器只跟随 3xx,故 200+Location 不会跳转

根因

与 历史排查文 相同:Typecho Response 默认 200,退出时 sendHeaders() 盖掉 PHP header(..., 302) 的状态码。

本次容器已重建为 typecho_zhuimeng(镜像 joyqi/typecho:1.3.0-php8.2-apache),PHP 为 8.2.30;旧补丁未带上。文件里虽有 header('Location: ...', true, 302),仍不够,必须 \Typecho\Response::getInstance()->setStatus(302)。

部署路径(重要)

项 值
容器名 typecho_zhuimeng(不是旧的 typecho2)
宿主机代码 /opt/1panel/apps/typecho/typecho_zhuimeng/data
容器挂载 .../data → /app
关键文件 /opt/1panel/apps/typecho/typecho_zhuimeng/data/usr/themes/Mirai/modules/oauth.php
容器内路径 /app/usr/themes/Mirai/modules/oauth.php

注意:容器内 /var/www/html 为空,不要再改那里。

修复操作

F=/opt/1panel/apps/typecho/typecho_zhuimeng/data/usr/themes/Mirai/modules/oauth.php
cp -a "$F" "$F.bak.$(date +%H%M%S)"

docker exec -i typecho_zhuimeng php << 'PHPEOF'
<?php
$f = '/app/usr/themes/Mirai/modules/oauth.php';
$c = file_get_contents($f);
if (strpos($c, 'setStatus(302)') !== false) { echo "already patched\n"; exit(0); }
$map = [
  "header('Location: ' . \$result['url'], true, 302);" => "\\Typecho\\Response::getInstance()->setStatus(302);\n            header('Location: ' . \$result['url'], true, 302);",
  "header('Location: ' . \$url, true, 302);" => "\\Typecho\\Response::getInstance()->setStatus(302);\n        header('Location: ' . \$url, true, 302);",
  "header('Location: ' . \$redirectUrl, true, 302);" => "\\Typecho\\Response::getInstance()->setStatus(302);\n    header('Location: ' . \$redirectUrl, true, 302);",
];
foreach ($map as $from => $to) {
  if (strpos($c, $from) === false) { fwrite(STDERR, "missing: $from\n"); exit(1); }
  $c = str_replace($from, $to, $c);
}
file_put_contents($f, $c);
echo "patched\n";
PHPEOF

grep -n "setStatus\|header('Location" "$F"
curl -sSI "https://www.zhuimeng.vip/oauth/qq?action=login&rurl=https%3A%2F%2Fwww.zhuimeng.vip%2F" | head -5

修复后确认

59:            \Typecho\Response::getInstance()->setStatus(302);
60:            header('Location: ' . $result['url'], true, 302);
123:        \Typecho\Response::getInstance()->setStatus(302);
124:        header('Location: ' . $url, true, 302);
191:    \Typecho\Response::getInstance()->setStatus(302);
192:    header('Location: ' . $redirectUrl, true, 302);

HTTP/2 302
location: https://graph.qq.com/oauth2.0/authorize?...client_id=1905398305...

QQ 互联:client_id=1905398305,回调 https://www.zhuimeng.vip/oauth/qq。

回滚

cp -a /opt/1panel/apps/typecho/typecho_zhuimeng/data/usr/themes/Mirai/modules/oauth.php.bak.HHMMSS \
      /opt/1panel/apps/typecho/typecho_zhuimeng/data/usr/themes/Mirai/modules/oauth.php

三、Cloudflare 根域 → www

现象

  • zhuimeng.vip 已能跳 www(旧规则)
  • zmxxk.cn、nanke.work 仍返回 200,进源站

DNS(修复时)

各 zone 均为:@ CNAME → www(橙云),www A → 175.178.106.193(橙云)。
CNAME 只统一解析目标,不会产生浏览器跳转。

错误规则(API 读出)

  1. zmxxk.cn zone 的 apex-to-www 误写成跳 zhuimeng.vip(规则建错 zone / 复制粘贴错误)
  2. nanke.work 用 full_uri wildcard "https://nanke.work"(无 /*),https://nanke.work/ 常匹配不上

正确规则(已用 API 写入,三站统一)

  • 相位:http_request_dynamic_redirect
  • If:(http.host eq "<apex>")
  • Then:Dynamic → concat("https://www.<apex>", http.request.uri.path)
  • 状态码:301,Preserve query string:ON

验证

curl -sSI https://zmxxk.cn/ | head -5
# HTTP/2 301
# location: https://www.zmxxk.cn/

curl -sSI https://zhuimeng.vip/
curl -sSI https://nanke.work/
# 同理 301 → 各自 www

路径与查询串会保留,例如:
https://zmxxk.cn/2498.html?x=1 → https://www.zmxxk.cn/2498.html?x=1

安全提示

会话中曾粘贴过 Cloudflare API Token;建议在 CF 控制台轮换/删除该令牌。


四、串站核对

URL 标题/站点
https://www.zhuimeng.vip/ 追梦学习库(Typecho + Mirai,PHP 8.2)
https://www.nanke.work/ 南柯的独白馆(Emlog,PHP 7.4)
https://www.zmxxk.cn/ 追梦学习库(Emlog Pro 2.6.33,PHP 7.4)

同机 Docker:typecho_zhuimeng / emlog-zmxxk / emlog-nanke 等,反代为 1Panel OpenResty。

说明:zmxxk.cn 后台标题「管理中心 - 追梦学习库」属正常,不是串到别的站。


五、zmxxk.cn 前台登录弹窗刷 HTML(Emlog + wind-max)

现象

  • 前台「登录」打开 #auth-modal 弹窗
  • 提交后红字区域刷出大段后台 HTML 源码(或表现为登录无效 / 请求失败)
  • 后台账号登录页 /admin/account.php?action=signin 本身正常

链路(主题 wind-max)

  1. 表单:POST /admin/account.php?action=dosignin,隐藏域已有 resp=json,前端 dataType: 'json'
  2. 成功:{"code":0,...} → 刷新首页
  3. 失败:Output::error → JSON;若响应不是 JSON,parseAuthError 会把整段 responseText 用 .text() 塞进弹窗 → 刷源码

根因

account.php 在 dosignin / signin 开头调用 loginAuth::checkLogged()。
已登录(浏览器仍带后台 cookie)时,原实现直接 emDirect("./") → 302 + 后台 HTML。
弹窗 AJAX 拿到 HTML 后无法 JSON.parse,就把源码当错误文案显示。

未登录时错误验证码已正常返回 JSON,例如:{"code":1,"msg":"验证码错误","data":""}(HTTP 400)。

部署路径

项 值
容器名 emlog-zmxxk
宿主机代码 /opt/1panel/apps/emlog/emlog-zmxxk/data
容器挂载 .../data → /app
关键文件 A /opt/1panel/apps/emlog/emlog-zmxxk/data/include/lib/loginauth.php(checkLogged)
关键文件 B /opt/1panel/apps/emlog/emlog-zmxxk/data/content/templates/wind-max/footer.php(parseAuthError)

修复思路(最终态)

  1. 治本:checkLogged() 在已登录且请求为 JSON/AJAX 时,返回 Output::ok()(或等价 JSON),不要 emDirect 跳后台页。
    迭代说明:曾用过偏宽的正则替换,一度导致异常空响应 /「请求失败」;已回滚后改为基于「已登录 + resp=json/AJAX」的明确分支(与 isLogin/cookie 判断一致),再验证。
  2. 治标:parseAuthError 在非 JSON 且内容像 HTML(以 < 开头或过长)时,显示短提示,而不是原文。

补丁命令(与线上一致的目标逻辑)

# A) loginauth:已登录 + JSON/AJAX → Output::ok,不要跳后台
LA=/opt/1panel/apps/emlog/emlog-zmxxk/data/include/lib/loginauth.php
cp -a "$LA" "$LA.bak.$(date +%H%M%S)"
# 将 checkLogged() 改为:若 userAuthCookie() 为真,且 POST/GET resp=json 或 X-Requested-With=XMLHttpRequest,
# 则 Output::ok()(或手写 code=0 JSON)后 exit;否则仍 emDirect("./");

# B) footer:parseAuthError 截断 HTML
F=/opt/1panel/apps/emlog/emlog-zmxxk/data/content/templates/wind-max/footer.php
cp -a "$F" "$F.bak.$(date +%H%M%S)"
# catch 分支:若 text 像 HTML 或 length>200,返回短文案:
# 「登录状态异常或服务器返回了页面,请刷新后重试(建议无痕窗口)」

验证

# 未登录:错误验证码应 JSON
curl -sS -D - -o /tmp/out1.txt -X POST 'https://www.zmxxk.cn/admin/account.php?action=dosignin' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data 'resp=json&login_type=pwd&user=test&pw=test&login_code=XXXX'
# 期望:HTTP 400 + application/json + {"code":1,"msg":"验证码错误"...}

# 浏览器:退出后台 / 无痕打开首页 → 弹窗登录
# 失败:短错误文案,不刷源码;成功:刷新首页

用户确认

2026-10-20 约 00:12(Asia/Shanghai):用户反馈「好像是可以了」。

回滚

# 用对应 .bak.HHMMSS 覆盖 loginauth.php / footer.php 即可

六、导航裸域(www 统一)

扫描结果(当时首页 HTML)

不带 www 的唯一路径 7 条(各出现约 2 次,桌面/移动):

  • https://zmxxk.cn/xuexiku(学习库)
  • https://zmxxk.cn/ruanjianku(软件库)
  • https://zmxxk.cn/shuji(图书库)
  • https://zmxxk.cn/yingshiku(影视库)
  • https://zmxxk.cn/yinyueku(音乐库)
  • https://zmxxk.cn/6.html(网站声明)
  • https://zmxxk.cn/19.html(关于我们)

后台导航表(用户截图)

上述项在 外观 → 导航 里地址已是 https://www.zmxxk.cn/...。
因此前台偶发裸域更可能来自主题缓存/旧 HTML,而非导航表未改。建议清 Emlog 缓存后强制刷新再扫;根域已 301 到 www,功能上可接受。


七、环境备忘

  • 面板终端:https://1pa.zmxxk.cn:2083/terminal(Grok Bot 所在网络超时;用户本机可进)
  • 主机:VM-20-5-debian,1Panel
  • 旧路径 /opt/typecho2 仍有历史数据残留,当前线上 Typecho 以 1Panel 应用目录为准
  • 服务器上 rg 可能未安装,用 grep 即可

八、变更文件一览

站点 文件 变更
zhuimeng.vip usr/themes/Mirai/modules/oauth.php 三处 setStatus(302)
Cloudflare 三 zone Redirect Rules apex host → www 301
zmxxk.cn include/lib/loginauth.php checkLogged JSON/AJAX 分支
zmxxk.cn content/templates/wind-max/footer.php parseAuthError 截断 HTML

记录结束。部署以服务器上实际文件与 Cloudflare Redirect Rules 为准。建议轮换曾粘贴过的 CF API Token。

分享到:
大流量号卡
软件目录

发表评论

请先 登录 再评论