thinkphp cookie与session需主动配置安全参数:全局在config/app.php中设secure、httponly、samesite、domain;反向代理时在public/index.php强制声明https;跨子域需同步配置cookie_domain和session.cookie_domain;代码层调用cookie::set()等必须显式传入安全选项。

Cookie 安全配置(必须设 secure、httponly、samesite)
所有安全属性必须在 config/app.php 的 'cookie' => [] 数组中统一声明,单独改 config/cookie.php 不生效:
- 'secure' => true:强制仅 HTTPS 下传输,上线必开;本地开发可临时设 false,但切勿提交
- 'httponly' => true:阻止 JavaScript 读取(如 document.cookie),防 XSS 窃取 token
- 'samesite' => 'Lax':缓解 CSRF 攻击,比 Strict 兼容性更好,比 None 更安全
- 'domain' => '.yourdomain.com':如需跨子域(如 user.example.com ↔ api.example.com),值必须以点开头,且 HTTPS 下必须同步启用 secure
- 'path' => '/':确保 Cookie 在全站路径下有效,避免设成 '/admin' 导致前端 JS 读不到
改完后务必执行 php think clear:runtime 清除缓存,否则新配置不生效。
反向代理下 HTTPS 识别(Nginx 终止 SSL 时必做)
当 Nginx 做 HTTPS 终止并转发 HTTP 到 PHP 时,ThinkPHP 会误判为非安全协议,导致 'secure' => true 实际失效。解决方法是在 public/index.php 开头(require 框架前)插入:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
这段代码优先级高于配置文件,确保后续所有 Cookie 和 Session 判断都基于真实协议环境。
Session 跨子域共享(仅配 cookie_domain 不够)
ThinkPHP 的 cookie_domain 只影响 Cookie::set() 写入的 Cookie,不影响 PHP 原生 session_start() 生成的 session_id Cookie。要真正实现跨子域登录态共享,需两步:
- 在 config/app.php 中设
'cookie_domain' => '.yourdomain.com' - 在 app/middleware.php 或 public/index.php(
require前)加:ini_set('session.cookie_domain', '.yourdomain.com');
注意:值必须是 .yourdomain.com(开头带点),不能是 example.com 或 *.example.com;本地开发禁用 localhost,改用 test.local 并 hosts 绑定。
控制器中写 Cookie/Session 时显式传参(防覆盖遗漏)
全局配置不会自动继承到每次 Cookie::set() 或 Session::set() 调用中。尤其对敏感数据(如 auth_token),必须手动指定安全选项:
Cookie::set('token', $val, ['secure'=>true, 'httponly'=>true, 'samesite'=>'Lax', 'expire'=>3600]);-
Session::set('user', $data, ['secure'=>true]);(TP6 中 Session 默认已受中间件保护,但显式更稳妥) - 若用助手函数:
cookie('role', 'admin', ['httponly'=>true, 'path'=>'/admin']);
特别注意:samesite => 'None' 时,secure 必须为 true,否则现代浏览器直接拒绝写入。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











