HTTP协议– cookie、session

  • Post author:
  • Post category:其他


大家学习http协议的时候不可避免会接触到cookie和session,今天我们简单说一下这两位,它们是什么,怎么工作,有什么样的区别和联系。

先说cookie吧,由于HTTP协议无状态的缺陷。WEB的设计者们提出了Cookie和Session两种解决机制。这里插一嘴,说下什么是无状态。

HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式web应用程序的实现。举个不太贴切的例子:

A:“大爷,我找马冬梅!”  B:“马什么梅啊?”

A:“马冬梅啊!”          B:“什么冬梅啊?”

当然,不是很贴切,那我们换个例子,在典型的网上购物场景中,用户浏览了几个页面,买了一个牛肉芝士汉堡和一杯蔓越莓气泡水。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么。

所以cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取cookies中包含信息,借此维护用户跟服务器会话中的状态。




本质上,cookie是浏览器访问服务器之后,由服务器传给浏览器的一段数据,保存在客户端。


在刚才的购物场景下,当用户选择了第一项商品服务器在向用户发送网页的同时,还发送了一段cookie,记录着那项商品的信息。当用户访问另一个页面,浏览器会把cookie发送给服务器,于是服务器知道他之前选购了什么。用户继续选购饮料,服务器就在原来那段cookie里追加新的商品信息。结帐时,服务器读取发送来的cookie就行了。

除此之外,cookie另一个典型的应用是当登录一个网站时,网站往往会请求用户输入用户名和密码,并且用户可以勾选“下次自动登录”。如果勾选了,那么下次访问同一网站时,用户会发现没输入用户名和密码就已经登录了。这正是因为前一次登录时,服务器发送了包含登录凭据(用户名加密码的某种加密形式)的cookie到用户的硬盘上。第二次登录时,(如果该cookie尚未到期)浏览器会发送该cookie,服务器验证凭据,于是不必输入用户名和密码就让用户登录了。

cookie是由服务器端生成,发送给浏览器,浏览器将cookie保存,下次请求同一网站时就发送该cookie给服务器,从而实现session保持。

服务器可以通过设置set-cookie响应头来设置cookie,比如下面这个:

  1. 首先test_cookie=CheckForPermission,表示这个cookie的键值对,每个cookie都会有自己的名称和值;
  2. expires=Mon,25-Feb-2019 00:28:09 GMT表示cookie的有效期,这个值如果不指定,那么默认值为到浏览器关闭之前为止;
  3. path=/,将服务器上的某个文件目录作为cookie的使用对象,简单的来说,是指定服务端有权限访问Cookie的路径,例如/var/,表示只有/var/下才可以访问cookie,默认为文档所在的目录;
  4. domain=.doubleclick.net,表示cookie所在的域。默认为创建cookie的域,也就是请求地址。

当然set-cookie的属性不止这些,还有secure、httpOnly等等,不做赘述。

接下来借下面的例子看看cookie的结构:

使用cookie时,服务端会对发送来的cookie进行校验,校验的内容为过期时间(expire)、域(domain)、路径(path)、协议(是否secure),从而判断cookie是否有效。

总的来说,cookie有好有坏,优点很多,比如不占用服务器资源,轻量简单,而且自定义有效时间尤为方便;但是弊病也不少,可禁用,容易截取,用户可见,容易篡改,长度有限(一般4K以下)等等。

Session

在开头提到,针对HTTP协议无状态的缺陷。WEB的设计者们提出了Cookie和Session两种解决机制。接下来我们就说说Session,它又是怎么工作的,和cookie有怎样的联系和区别,又有什么限制。

作为后来者的Session,比起老大哥cookie,更加简单些,最本质的区别:它是保存在服务器端的。这就必然会造成服务器端的存储压力增加,但是使用起来更加安全和方便。

Session的原理就是,客户端浏览器第一次访问服务器的时候,服务器把客户端信息以类似散列表的结构记录在服务器上,生成一个Session和一个Session ID用以标识,这个Session ID将被在本次响应中返回给客户端保存。而当客户端浏览器再次访问时会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,与保存的进行对比,找到这个用户对应的session。

简单来说,就像我们订蛋糕,cookie服务生对你说:“这是您的凭据请拿好,凭此单来取蛋糕,谢谢您的光临~”,当你再来的时候把小票递给服务生,服务生看了之后按照信息给你蛋糕;而session服务生就不一样了,你第一次来订蛋糕,session服务生会给你办张会员卡,在登记表上记录你的信息,等你再来的时候会直接按卡号查表,然后说:“尊贵的XX会员,您的蛋糕已经做好了,请您拿好,欢迎下次光临~”



Session ID在客户端保存的方法也有几种。

首先,当cookie未被禁用时,session是依赖于cookie的,把session的id 放在cookie里面,这种情况下name往往和session有关;

当cookie禁用时(比如手动禁用),我们经常使用的一种方法叫URL重写,即把session id直接附加在URL路径的后面。比如https://www.baidu.com/link?url=6PbvsxrkciVmIwG0SOJxfm6izqEh5aJyLsubX;jsessionid=……..

不过,session同样也有弊病,大量的并发请求下session可能溢出,session_id也可能重复等等。



版权声明:本文为m0_56788835原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。