如何在 PHP 中实现跨子域名的 Session 共享

6次阅读

如何在 PHP 中实现跨子域名的 Session 共享

本文详解通过正确配置 session_set_cookie_params() 和 session.cookie_domain,使登录子域名(如 login.testsite.co.kr)产生的 session 可被其他同根子域名(如 100.testsite.co.kr)共享,解决因 cookie 域名范围不匹配导致的登录态丢失问题。

在多子域名架构中(例如 testsite.co.kr、login.testsite.co.kr、100.testsite.co.kr),实现统一登录态的核心在于:让 PHP 生成的会话 Cookie 被所有目标子域名识别并发送 。常见失败场景(如仅在 login.testsite.co.kr 登录后无法在 100.testsite.co.kr 读取 $_SESSION[‘userid’])几乎均源于 Cookie 的 作用域(Domain)设置不正确。

✅ 正确配置要点(关键三步)

  1. 必须在 session_start() 之前调用 session_set_cookie_params(),且显式传入带前导点号的根域名;
  2. session.cookie_domain 配置需与之保持一致(推荐在代码中统一设置,而非仅依赖 php.ini);
  3. Cookie Path 应设为 ‘/’,确保路径全覆盖;过期时间设为 0(会话级)即可。

以下是修复后的标准写法(兼容 PHP 4.3+,但强烈建议升级至 PHP 8.x):

// session_test.php —— 所有子域名下均使用此配置 ini_set('session.cookie_domain', '.testsite.co.kr'); // 注意开头的点号!session_set_cookie_params(0, '/', '.testsite.co.kr'); // ⚠️ 必须在 session_start() 前!session_name('mysession'); session_cache_limiter('no-cache, must-revalidate'); session_start();  $_SESSION['userid'] = 'kim';

? 为什么必须加前导点号(.testsite.co.kr)?浏览器 Cookie 规范要求:带前导点号的 Domain 值表示“匹配该域名及其所有子域名”。若写成 testsite.co.kr(无点号),现代浏览器(Chrome/Firefox/Safari)将拒绝将其发送至任何子域名,仅限精确匹配主域名。这是导致 login.testsite.co.kr 登录后其他子域无法读取 Session 的根本原因。

⚠️ 常见陷阱与注意事项

  • 顺序不可颠倒:session_set_cookie_params() 必须在 session_start() 之前调用,否则无效;
  • 避免重复配置:若已在 php.ini 中设置了 session.cookie_domain,仍建议在代码中显式调用 session_set_cookie_params(),确保行为可预测;
  • 协议与 端口 一致性:HTTPS 子域与 HTTP 子域之间默认无法共享 Cookie(受 Secure 标志限制),如需混合支持,需额外处理 session.cookie_secure;
  • PHP 版本警示 :原文提到使用 PHP 4.3(发布于 2003 年),该版本已严重过时,不支持 SameSite、HttpOnly 等安全属性,且存在已知 Cookie 解析缺陷。 生产环境务必升级至 PHP 8.1+,并启用:
    session_set_cookie_params(['lifetime' => 0,     'path'     => '/',     'domain'   => '.testsite.co.kr',     'secure'   => true,       // 仅 HTTPS 传输     'httponly' => true,       // 禁止 JS 访问     'samesite' => 'Lax'       // 防 CSRF ]);

✅ 验证是否生效

部署上述代码后,按以下步骤验证:

  1. 在 login.testsite.co.kr/session_test.php 中执行,设置 $_SESSION[‘userid’];
  2. 立即访问 100.testsite.co.kr/session_test.php(内容含 var_dump($_SESSION););
  3. 若输出包含 ‘userid’ => ‘kim’,说明跨子域 Session 共享成功。

? 提示:可借助 浏览器 开发者 工具 → Application → Cookies,检查 PHPSESSID Cookie 的 Domain 字段是否为 .testsite.co.kr —— 这是最直观的验证依据。

立即学习PHP 免费学习笔记(深入)”;

通过精准控制 Cookie 的作用域与生命周期,跨子域名 Session 共享并非难题。核心原则始终是:让服务端生成的会话标识,以浏览器认可的方式,可靠地抵达每一个需要它的子域名。

text=ZqhQzanResources