历时两天,终于解决了ThinkPHP5框架接入腾讯云TEO无法登录后台的问题。

李洋博客08-07871阅读0评论

温馨提示:这篇文章已超过34天没有更新,请注意相关的内容是否还可用!

好久没有写教程文章了,不是别的仅仅是因为AI爆火之后没有什么值得记录的,这不今儿就来了,起因有一个TP5框架项目需要引入CDN,在综合选择之后部署了腾讯云的TEO,也就是边缘加速,一切部署之后就下班了,结果昨天甲方告知后台系统无法登录,我想着小意思哈,肯定是缓存问题,我把缓存设置下就行了,结果还真不是我以为我以为的就是我以为的!!!

历时两天,终于解决了ThinkPHP5框架接入腾讯云TEO无法登录后台的问题。 第1张

先说下结论

腾讯云 TEO(EdgeOne)免费版会在回给浏览器的响应中剥离 Set-Cookie(workbuddy说的,不是我说的),依赖「服务端 Session + PHPSESSID Cookie」的 ThinkPHP 5.1 后台因此无法维持登录、陷入登录循环。

修复办法是用 TEO 边缘函数在边缘节点把源站的 Set-Cookie 重新下发,不需要修改服务器的源代码。

一、环境

  • 框架:ThinkPHP 5.1 LTS

  • 运行:Nginx 1.24 + PHP 7.4 + MySQL 8.0

  • 接入:域名 www.itlaoli.com 走 TEO 加速(回源 443、强制 HTTPS、HSTS/2)

  • 后台:模块 admin,登录链路 Login/checkLogin → 写 session('admin',...) → JS 跳转 Index/indexCommon::initialize() 校验 session

二、现象

登录页能打开,输入账号密码点登录,提示成功却又跳回登录页,无限循环。使用服务器IP解析其他域名访问正常,走 TEO 不行。

三、排查时间线(部分关键节点)

  1. 先怀疑 HTTPS 识别 isSsl() 失败 → 源站自己监听 443,排除。

  2. 看请求头 PHPSESSID 一致 → 排除「浏览器 cookie 没带上」。

  3. 怀疑 session 没落盘 → php -i 发现走 Redis,且 sess_test.php 证明 Redis 能写,排除。

  4. checkLogin 响应头没有 Set-Cookie → 方向转向「响应侧 cookie 没种下」。

  5. Session::close()、改 Nginx Cache-Control: private、独立 location 全 404、server 级 if 语法错 → 均无效。

  6. 直连 htgl 登录成功(日志 fr89... 一路到 welcome),wwwPHPSESSID=空实锤 TEO 剥离 Set-Cookie

  7. 查官方文档 1552/84080「设置 Cookie」→ 锁定边缘函数方案。

  8. 部署边缘函数时踩进两个新坑:onRequest 入口报错、Content-Encoding 冲突空白页 → 修正后成功。

四、根因

TEO 免费版「修改 HTTP 节点响应头」能力仅有 设置/删除/增加没有「保留/透传」,对 Set-Cookie 默认剥离。浏览器永远拿不到 PHPSESSID,每次请求都是新会话,登录即失效。

而且按照workbuddy的说法了,不能设置增加,只能设置透传/保留,但是TEO没有,至少免费版没有,收费版我用过不晓得哈。

解决方案(最终可用代码)

TEO 规则触发的边缘函数(匹配 /admin/*):

async function handleRequest(request) {
  // 回源获取响应
  const response = await fetch(request);

  // 读取源站 Set-Cookie
  const setCookie = response.headers.get('set-cookie');
  if (!setCookie) {
    return response;
  }

  // 复制头,补 Set-Cookie
  const newHeaders = new Headers(response.headers);
  newHeaders.set('Set-Cookie', setCookie);

  // 关键:删除 Content-Encoding / Content-Length,避免 body 与编码声明不一致
  newHeaders.delete('Content-Encoding');
  newHeaders.delete('Content-Length');

  return new Response(response.body, {
    status: response.status,
    statusText: response.statusText,
    headers: newHeaders
  });
}

addEventListener('fetch', (event) => {
  event.respondWith(handleRequest(event.request));
});

原理:边缘函数从源站响应读取 Set-Cookie,在「TEO 剥离」之前重新下发,浏览器正常拿到 PHPSESSID,session 得以维持。
历时两天,终于解决了ThinkPHP5框架接入腾讯云TEO无法登录后台的问题。 第2张

后续增加了@301重定向www,因为边缘函数接管了/admin/*,所以服务器设置的重定向失效,导致没有www的网站提示账号密码错误,所以我新增了重定向,有需要的自己添加。

触发规则:

匹配类型选择【URL path】,运算符设置【等于】,值设置【/admin/*】(根据项目后台的实际目录设置,图片为演示站)

历时两天,终于解决了ThinkPHP5框架接入腾讯云TEO无法登录后台的问题。 第3张

踩坑点(文章重点)

首先我使用了很多AI软件,包括不限于Qoderwork、TRAE Work,千问、文心一言,在最后放弃的一瞬间,先说为什么放弃,因为真的没有办法实现了,只能暂时用其他域名绑定项目,然后解析服务器IP来访问后台(兜底方案)。我真的是不了解TP5框架,说什么session我也听不懂,可以说小白刚刚解除电脑那个级别吧,然后我就像既然是session有问题,去官网搜一下关键词试试,当时呢我也看不懂,毕竟文档都是留给大佬看的,所以我就把最后的稻草放在了workbuddy(不是说只要它才能解决问题哈)里,然后经过三轮调试,终于在无痕模式下成功登入,但是能感觉到有一丢丢的延迟,可能是传输set-session或者其他原因吧。无论怎样算是成功了。聊聊跟AI总结的几个采坑点,自己记录。

  1. 别看错请求Set-Cookie 只在「建立会话那一次」出现(登录页首次加载的 GET 响应头),不是 checkLogin POST。在 POST 上看到「只有 Cookie、没有 Set-Cookie」是正常的,别被误导。

  2. 先区分请求侧还是响应侧:F12 看 checkLogin 响应头有没有 Set-Cookie,一眼定位是「cookie 没带上」还是「cookie 没种下」。

  3. 别乱猜 HTTPS:源站自身监听 443 时 isSsl() 正常,问题未必在 HTTPS。

  4. session 驱动看 php.ini:TP5 config/session.phptype => '' 时,session 由 php.ini 的 save_handler 决定(本例是 phpredis,不是文件),排查别被路径误导。

  5. Nginx 独立 location 会 404location ~ ^/admin/ { add_header ... } 优先级高于 PHP 处理器且无 fastcgi,会把后台打 404。要加响应头必须放进 enable-php-74.conf 的 PHP location 内。是的你没看错,我都已经开始修改nginx规则了,但是无效,属于无用功。

  6. Cache-Control: private 救不了:TEO 对 Set-Cookie 是硬剥离,Cache-Control 出现 ≠ 成功,判定标准始终是 Set-Cookie 是否在响应头出现。通过TEO规则引擎配置了Cache-Control头,但即便显示也是无用,原因不在这。

  7. 边缘函数入口别用错:TEO 规则触发的边缘函数用 addEventListener('fetch', ...)(文档 1552/84080);onRequest(context) 是 EdgeOne Pages/Makers 的写法,用错会 Error return from script

  8. Content-Encoding 冲突:重建 Response 时若保留 Content-Encoding: gzip 但 body 已被运行时解压,浏览器会 ERR_CONTENT_DECODING_FAILED 白屏。必须 delete('Content-Encoding')delete('Content-Length')

  9. 免费版能力受限:「修改 HTTP 节点响应头」只有设置/删除/增加,无法透传;后台这类动态鉴权路径,要么直连源站,要么上边缘函数。

最后

 我这两天的折腾到如今也还是不理解,为什么像WordPress和zblog可以直接配置TEO而没有问题,为什么TP框架进寸步难行呢?可能就是因为不了解这个程序,毕竟这样两天的时间需要记录下问题以及解决办法,但是我感觉这个不是问题的根本虽然现在能登陆了,可是为什么会有一丢丢的延迟,这个在服务器直接登录是察觉不到的,这就可能存在问题。我还去百度搜索了,也没有结论,难不成大家的TP框架都没有部署CDN么?还是说都是收费版没有任何问题呢?很费解,只能说自己的技术和经验还是少的可怜,除了zblog其他程序一概不知,惭愧惭愧~~~好了,大神有好的方案可以留言告诉我,静待佳音~~~

文章版权声明:除非注明,否则均为李洋博客原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
AddoilApplauseBadlaughBombCoffeeFabulousFacepalmFecesFrownHeyhaInsidiousKeepFightingNoProbPigHeadShockedSinistersmileSlapSocialSweatTolaughWatermelonWittyWowYeahYellowdog
评论列表 (暂无评论,871人围观)

还没有评论,来说两句吧...

取消
微信二维码
微信二维码
支付宝二维码