thinkphp cookie安全配置入口在config/app.php的'cookie' => []数组中,必须显式设置'secure' => true、'httponly' => true、'samesite' => 'lax'等参数,反向代理下需强制声明$_server['https'] = 'on'或写死secure=true,否则https环境仍不生效。

ThinkPHP 默认不开启 Cookie 安全防护,httponly 和 secure 都是 false,不配置就等于裸奔——哪怕你用了 HTTPS,PHPSESSID 仍可能被 JS 读取、明文传输、URL 拼接泄露。
ThinkPHP 的 cookie 配置入口在哪
不是 config/cookie.php,也不是 config/cache.php,5.1 在 config.php 或 config/app.php 的 'cookie' => [] 数组里;6.x 统一收口到 config/app.php 的同名配置块。漏改这里,控制器里用 Cookie::set() 手动传参也大概率被全局配置覆盖。
必须显式写入:
-
'httponly' => true:阻止document.cookie读取会话 ID -
'secure' => true:强制仅 HTTPS 发送(反向代理后需额外处理) -
'samesite' => 'Lax':缓解 CSRF,设'None'时secure必须为true -
'domain' => '.yourdomain.com':注意开头的点号,否则子域不共享
反向代理下 Secure 标志不生效怎么办
常见现象:Nginx 终止 HTTPS,转发 HTTP 请求给 PHP,ThinkPHP 检测 $_SERVER['HTTPS'] 为空,自动禁用 secure——浏览器 DevTools 显示 Cookie 缺少 Secure。
两种可靠解法(选其一):
- 在
public/index.php开头强制声明:if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on'; } - 直接在
config/app.php的 cookie 配置中写死'secure' => true,不依赖运行时检测
别用 Request::isSsl() 判断后动态赋值——它和 Cookie 发送逻辑不同步,容易失效。
登录后不 regenerate_id 就等于白设 httponly
httponly 防的是 XSS 窃取,但防不了会话固定(Session Fixation)。攻击者只要诱导用户访问带固定 PHPSESSID 的链接(如 /login?PHPSESSID=attacker123),登录成功后这个 ID 就直接变成合法会话。
ThinkPHP 不自动做这一步,必须手动加:
- 认证通过后、写入用户数据前,立刻调用
session_regenerate_id(true) -
true参数不能省——它会删除旧 session 文件,否则残留 ID 仍可被重放 - 别用
Session::clear()或Session::destroy()替代,它们只清数据,不换 ID - 确保该调用发生在
session_start()之后、且早于任何$_SESSION赋值
为什么 JS 还能读到 Cookie
检查三处:
- 是否全局配置了
'httponly' => true,且没被控制器里Cookie::set('name', $val, ['httponly' => false])覆盖 - 是否用了原生
setcookie()但没传第 7 个参数(httponly),PHP 7.3+ 推荐用数组语法显式声明 - 浏览器是否缓存了旧 Cookie——清除浏览器 Cookie 或硬刷新(Ctrl+F5)再测
最易忽略的是:ThinkPHP 5.1 默认 httponly 是 false,6.x 默认是 true,升级时只改了 secure 却漏掉 httponly,或者误以为框架“默认安全”而没动配置。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











