详解cookie和session的运作机制

2018/10/18 18:17

前言

最近有热心的同学评论开学以来公众号的推文简单,没有亮点。所以,笔者会重新平衡和丰富一下公众号的推文,有建议或意见欢迎下方留言!

同时,非常欢迎广大读者投稿!投稿不需要考虑排版问题!

本篇环境

后台:PHP5.2,apache,案例源码

客户端:火狐浏览器,burp(观察HTTP的请求响应头)

(其实,如果对协议和后台处理逻辑清楚的同学看本文的话,理解起来会很快的。)

大纲

1.什么是cookie?在后台如何创建?http中的cookie各个参数的值是些什?存在哪里?(上篇)

2.什么是session?如何使用session?存在哪里?(中篇)

3.session的使用方法:使用session写一个网站访问的简单计数器(案例虽简单和普遍,但会解释清楚一些细节性的参数)(中篇)

4.session的回收机制(下篇)

1

COOKIE

0x01.cookie作用

由于HTTP协议的特性,用户访问网站时所建立的连接的上下是互不联系和相关的。

HTTP请求每次建立的连接都是独立的。用户第一次访问网站时,需要进行身份校验,你需要输入账户和密码,但当在该站跳转页面时,却不需要再输入账户密码了,网站依然认识你的登录身份。

这是为什么呢?当然,HTTP连接每次都是独立且上下互不相连,这句话没问题;你发送不同的HTTP请求,网站却认识你的身份,这也没问题。这就是问题的关键:WEB站点如何认识你的身份?

第一个关键词就引出来了:COOKIE

当用户发送http请求时,请求包是很单纯的一个包。

(友情提示:下图的ip你们是访问不到的)

但是相应包会带来一个header,setcookie参数,要求浏览器携带此cookie

右图的Set-Cookie的header头,会使浏览器存储这个cookie值来作为之后一段时间与web网站交互的身份凭证。

比如我接受这个cookie后,再次发送几次请求包

那么,我删了cookie再发送一下请求包

经过以上试验,你就清楚使怎么回事儿了。你发起对web的请求,网站会返回给你一个cookie作为你这个用户的标识,你携带这个标识去访问,web页面会逐渐增加那个访问次数的数值。当你没有携带cookie的时候,后台会认为你是第一次访问该页面,并返回一个setcookie的header,给你一个cookie。

0x02.cookie的创建

在后台使用setcookie参数就可以创建cookie头部了。

//setcookie('参数名','参数值',[可选参数:有效期,服务器路径,访问域名,是否只通过HTTPS连接来传输cookie,布尔:是否开启HTTP_ONLY]);

//HTTP_ONLY在php5.2及其以上版本支持

setcookie('Username','NUC_SECURE');

//设置cookie

echo $_COOKIE['Username'];

//打印出接受到的用户传来的cookie

接下来我访问4.php

然后我携带cookie来访问

页面打印出了用户的cookie值。

这样,使用setcookie函数的一个简单实例就完成了。

(注:COOKIE在后台是全局变量,只要用户的请求包不论是GET参数,请求行的头部参数,POST参数,都可以成功传入cookie的)

0x03.参数介绍:就说两个参数:有效期,HTTP_ONLY

0x0301:有效期

//setcookie('参数名','参数值',[可选参数:有效期,服务器路径,访问域名,是否只通过HTTPS连接来传输cookie,布尔:是否开启HTTP_ONLY]);

比如我重写一下上文后台的setcookie()

setcookie('User','CD!',time()+1440,'/','',0,TRUE);

echo $_COOKIE['Username'];

现在我访问该页面

头部返回了:

“Set-Cookie: User=CD%21; expires=Thu, 18-Oct-2018 09:50:20 GMT; path=/; httponly”

是不是?而之前的返回的仅仅是

“Set-Cookie:User=NUC_SECIRE”对不对?

后台setcookie的状态不一样,返回的setcookie的值当然也不一样。

先说一下有效期:

笔者写到现在明明以及2018年10月18号17:31了,

后台的有效期参数为‘time()+1440’(24分钟,默认单位是:秒),

但是头部返回的寿命点是:expires=Thu, 18-Oct-2018 09:50:20 GMT,

这才早上九点五十啊?会不会出错了,这个cookie一到浏览器就是失效的?

其实,你把expires从GMT换算为中国时区的时间(cookie的生命终点),再减去你现在手表的时间,就是cookie的寿命。

的确,如果写成

setcookie('User','CD!',time()-1);(时间设置成过去时)

或者setcookie('User','');(设置cookie的值为空)

这的确是会要求浏览器删除掉cookie,浏览器也会照做。

但是,expires=Thu, 18-Oct-2018 09:50:20 GMT这个时间确实是正确的。

时间后面的‘GMT’的意思,就是‘格林尼治时间’(高中地理课本英国那个小木屋的时区时间),涉及到时区的时间差异了。所以,当你发现cookie的生存尽头居然是过去的时间,不要惊异。换算成中国时间的话,就是你所理解的cookie寿命尽头。

0x0302:HTTP_ONLY

setcookie('User','CD!',time()+1440,'/','',0,TRUE);

echo $_COOKIE['Username'];

setcookie()的最后一个参数就是TRUE,设置了HTTP_ONLY属性

HTTP相应包的setcookie的头部如下:

HTTP_ONLY是个什么属性呢?在PHP中,php5.2及以上是支持HTTP_ONLY属性和HTTP_ONLY的全局属性的。

HTTP_ONLY属性,可以使cookie不被客户端浏览器的js执行。javascript访问浏览器的cookie,是从document对象中访问。当cookie被设置为HTTP_ONLY的属性,cookie将不被javascript获取。

注意

之所以有这个参数,当然是为了‘有效减少’XSS盗取Cookie啊~~~

之所以说是‘有效减少’,而不敢直接说成“杜绝xss窃取cookie”,是有原因的。

比如,曾经防御不了代理xss访问cookie,曾经没防御flash插件走程序拿走cookie,没能防御某些浏览器插件导致header头部泄露使cookie被窃取。

当然,HTTP_ONLY还是能防御大部分hacker写的xss攻击的。

谈到HTTP_ONLY的全局属性,这是从后台设置的。

打开后台php的设置文件php.ini,查看“session.cookie_httponly = ”属性。

该属性默认为空,即默认setcookie的有关HTTP_ONLY参数是false(当然开发者可以单独在这个函数手动设置这个参数)。

将“session.cookie_httponly =”改写为“session.cookie_httponly = 1”,可开启全局的cookie的HTTP_ONLY属性,重启服务器,默认所有的setcookie()开启了HTTP_ONLY属性。很大程度上,可减少网站xss的危害程度。

0x04.cookie的存储

cookie是存储在客户端的浏览器上的。

注意

WEB服务器默认可不存储cookie。

当然,某些框架为了更调理、方便的校验cookie,活用cookie,通常在后台专门存储用户的cookie,有兴趣的同学可以自己做一个类似框架。

当然,笔者要讲的情况是基础,默认的情况是web不存储cookie

我们也不用关心cookie存在哪个盘符,哪个路径下,查看、修改cookie很简单。

打开浏览器

按‘F12’,进入开发者模式。

cookie就存储在这里。

上篇终。

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20181018G1S87000?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券