Programmer

Will Change The World

关于Cookie过期时间的一些坑

背景

最近做了个项目,大致流程是这样的:微信中打开A页面,判断是否登陆,未登录的话跳转至微信授权并设置登陆cookie信息,然后重定向回A页面。QA提了个bug,打开页面后一直在授权地址和A页面之间循环跳转。上去找QA看了下现场,发现确实是这样,而且只有iPhone 6 plus会这样,其他机型正常,捕获了授权链接等等也都是没有问题。让QA把链接发我就灰溜溜的下楼了……然而,下楼的过程中,灵光一闪突然想到了日期的问题(有时候找bug真的要看运气,要是没想到时间问题,真的不知道要耗多长时间……),会不会是那台机器时间设置有问题?立马问了QA,果然,时间设置到了2018年3月1号……一切都真相大白了。

原因

原因很简单,授权完毕后设置登陆信息cookie,过期时间是按照服务器的正常时间进行设置的,而那台机器的系统时间设置到了2018年的3月1号,因此会导致cookie信息过期,从而一直在授权页面之间跳转。

复现

本着负责的态度,打算写个demo验证下上述现象。

1.服务端代码

服务端代码很简单,就是设置cookie而已。

if (!isset($_COOKIE['name'])){
     setCookie('name','111111',time()+300,'/');
}

var_dump($_COOKIE);

 

2.客户端表现

设置系统时间为一个月之后,然后访问localhost/cookie.php,输出如下:

《关于Cookie过期时间的一些坑》

cookie信息如下:

《关于Cookie过期时间的一些坑》

cookie设置成功,这里没有任何问题。

理论上来说,再次刷新浏览器,输出应该也是没有信息的,因为cookie过期了,然而事实却不是这样:

《关于Cookie过期时间的一些坑》

whatttttt??? 为什么cookie还在?

静下来想了想,发现了问题:我是用本机作为服务端,那么时间也是经过修改的,这样cookie是没有过期的。

 

第二次尝试,在虚拟机上搭建服务器,虚拟机上的时间是正常时间,然后访问虚拟机,

重复第一次的步骤,然而惊讶的发现……居然cookie还在!!!

查看响应头信息:

《关于Cookie过期时间的一些坑》《关于Cookie过期时间的一些坑》

可以看到,cookie的过期时间是2018年2月2日,然而系统时间已经调到了2019年……

又试着改了下系统时间,然后刷新页面,发现cookie信息没了!然而再次刷新浏览器,cookie信息又出现了,并且刷新多次也还是一直在。再次更改系统时间,cookie信息消失了……

也就是说,只有种下cookie之后更改系统时间才会生效,在种cookie之前更改系统时间是没有效果的!

不信邪的我又换了Firefox、Opera等浏览器,结果同chrome一致。直到我换了IE,cookie信息一开始就不在了……

想来想去不明白是为什么?不由得对浏览器判断cookie过期的机制有点兴趣,查阅了一些文档之后终于知道为什么了。

 

原来,在HTTP/1.0的时候,cookie的过期是根据expires来判断的,在HTTP/1.1的时候,变成根据Max-Age来判断了。关于这两者的区别,简单来说是这样:

  • expires是设置一个过期的时间点;Max-Age是设置还有多久过期。类似于相对路径和绝对路径的关系。

详细对比推荐看这篇文章:HTTP Cookies: What’s the difference between Max-age and Expires?

可以看出来,Max-Age是与系统时间无关的,不管系统时间设置的是什么时候,都是相对于系统时间一段时间之后过期。

chrome、Firefox等现代浏览器是支持Max-Age的,因此在种cookie之前,更改系统时间,是没有关系的,cookie会仍然在。然而种下cookie之后再更改系统时间,这个时候,浏览器判断当前时间减去种cookie的时间差大于Max-Age了,因此cookie就失效被删除了。

IE不支持Max-Age,因此,在种cookie之前修改系统时间,在判断过期的时候根据系统时间大于expires设置的时间点,cookie自然就被判过期从而被删除了。

 

到这里,还剩最后一个疑点:按照以上的说法,应该是微信不支持Max-Age选项,可是经过测试,实际上是支持的,那又是怎么回事呢?

 

最后终于找到了元凶:php的版本太低,设置cookie的时候没有Max-Age!!!php从5.5开始设置cookie的时候会有Max-Age,在5.5之前是没有Max-Age的,如下图:

《关于Cookie过期时间的一些坑》

所以只能通过expires来判断,所以一切都真相大白了。

 

总结

  1. 通过修改系统时间,可以更改cookie的存活时间
  2. expires和Max-Age都可以用来设置cookie过期信息,同时存在且均支持时以Max-Age为准。
点赞

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注