session.cookie_domain必须在session_start()前设置,否则无效;domain值须为'.example.com'格式,且需配合Redis等中心化存储和JWT等跨域方案。

session.cookie_domain 必须在 session_start() 前设置
这是最常踩的坑:只要 session_start() 执行过了,再调用 ini_set('session.cookie_domain', '.example.com') 或 session_set_cookie_params() 就完全无效。浏览器收到的 Cookie Domain 仍是当前完整域名(如 shop.example.com),其他子域根本收不到。
正确做法是确保所有 session 相关配置都在 session_start() 之前完成:
- 用
ini_set()设置session.cookie_domain、session.cookie_secure、session.cookie_httponly等 - 或统一用
session_set_cookie_params()传数组(PHP 7.3+ 推荐) - 若使用
session_set_cookie_params(),必须带'samesite' => 'Lax'或'None',否则现代浏览器可能拒绝发送 Cookie - HTTPS 环境下,
'secure' => true是强制要求,否则samesite=None会被浏览器忽略
domain 参数必须带前导点号 .example.com
写成 example.com 或 www.example.com 都不行——前者被部分浏览器视为非法值而静默丢弃,后者只对 www 生效。唯一可靠写法是 '.example.com'(注意开头的点)。
这个点号不是可选格式,而是告诉浏览器“该 Cookie 对 example.com 及其所有子域(api.example.com、admin.example.com)均有效”。实测中,不加点号在 Chrome 120+ 和 Safari 17+ 上大概率失效。
立即学习“PHP免费学习笔记(深入)”;
示例代码(PHP 8.1+):
使用 Playwright 为 jimeng.jianying.com 管理浏览器会话,导入 cookies/localStorage 以自动化视频生成工作流,支持图片上传等功能
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax'
]);
session_start();
跨顶级域(a.com ↔ b.net)无法靠 cookie_domain 解决
浏览器同源策略是硬限制:.a.com 和 .b.net 完全无关,session.cookie_domain 再怎么设都无效。这时候继续折腾 Cookie 没意义,得换思路。
可行路径只有两条:
- 前端透传 session_id:登录后跳转时把
sid=xxx拼进 URL,目标站用session_id($_GET['sid'])+session_start()加载——但必须加 Referer 校验或一次性 token,否则极易被劫持 - 彻底放弃 Session 依赖 Cookie 的模式,改用 JWT:服务端签发含
user_id、exp的 Token,前端存 localStorage,每次请求带Authorization: Bearer xxx,后端验证签名并解析用户身份
JWT 方案虽然要重写鉴权逻辑,但规避了所有 Cookie 跨域限制,也更适合前后端分离和微服务架构。
Redis 存储 + 共享 domain 是完整方案的必要组合
只设对 session.cookie_domain 不够——Cookie 能传过去,不代表 Session 数据能读到。如果各子域 PHP 还默认用文件存 Session(session.save_handler = files),那 shop.example.com 写的 session 文件,api.example.com 根本找不到。
必须配合中心化存储:
- 启用 Redis:设
session.save_handler = redis,session.save_path = "tcp://127.0.0.1:6379" - 所有子域共用同一套 Redis 连接参数,确保
session_id一致时读到的是同一份数据 - 若用自定义 Session 处理器,注意
read()方法返回的序列化字符串必须与当前 PHP 的session.serialize_handler兼容(默认php)
最后提醒一句:即使所有配置都对,也要打开浏览器 DevTools → Application → Cookies,确认 Domain 列显示的是 .example.com,而不是空值或具体子域名——这是唯一可信的验证方式。


















