本文改编自邮件通知
邮件通知需要针对 https 访问的 cookie 设置 secure 为 true。
之前都比较简单粗暴都是默认的 false。
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
基本可以认为 Chrome 限制每个域名下可以存储 180 个 cookie。这里有一点要注意:每个域名 180 个 cookie 的限制是针对根域名的,即:a.mengkang.net, b.mengkang.net 和 *.mengkang.net 共享这180个限制。
RFC-6265 中对cookie逐出策略的规定,中规中矩,没有特殊对待none-secure的cookie,cookie逐出算法是LRA(least-recently accessed)。
Chrome 58 开始实行他们对 cookie 提出的草案:当cookie达到Chrome限制时(180个),none-secure的cookie总是被优先逐出的。
这样就有可能导致一些登录态的 cookie 被删掉。
一般网站可能遇不到这个问题,但是网站大了,各个子域名使用的 cookie 比较多。就有触发这个问题了。
完美解决方案是规范 cookie 的使用(众多项目,不可太能)。折中解决方案,把重点 cookie 中的 secure 设置为 true。
php 的解决方案可以如下
$secure = false;
if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS'])) {
$secure = true;
}else if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
&& $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
$secure = true;
}else if (isset($_SERVER['HTTP_X_CLIENT_SCHEME'])
&& $_SERVER['HTTP_X_CLIENT_SCHEME'] == 'https') {
$secure = true;
}
setcookie ($name, $value, $expire, $path, $domain, $secure, $httponly)