Cookie和Session
在日常生活中,作为用户的我们经常与互联网中的大大小小的网站进行交互,例如查看新闻、购买商品等等。在浏览商品的时候,我们经常会将喜欢的商品暂时加入购物车,以便后面的时候一起购买。但对于同一个商城的若干次页面请求当中,服务器在后台当中是如何判别该购物车是哪一个用户的呢?
对于一次网络的请求,一般都是基于HTTP,但是HTTP是一种无状态协议(即不保留管理用户数据),所以不能够单纯依靠HTTP协议。为了针对这一现象,运生出了Cookie(面向客户端)和Session(面向服务端)两种通用方案。
Cookie
Cookie,中文名称为”小型文本文件“,指某些网站为了辨别用户而存储在用户本地终端上的数据(通常经过加密)。
用途
在之前的介绍当中,我们谈及到了购物车。当用户选购一件商品的时候,服务器在向用户传递该商品页面的同时,还附加发送了一段Cookie(Response - Set-Cookie)。在用户点击加入购物车按钮时,客户端会将该商品的Cookie发送给服务器,这样,服务器就明白该用户的选购了哪些商品。最后,当用户点击查看购物车时,客户端会发送该用户的Cookie给服务器(Reuqest - Cookie),服务器就会回传该用户的购物车记录。
使用Cookie的另外一个经典场景是当登陆一个网站时,网站往往会请求用户输入用户名和密码,并且用户可以勾选“下次自动登录”。当用户勾选了,那么下次访问同一个网站的时候,用户会自动跳过登录界面,跳转至主页当中。这其中的过程就是,在前一次正常的登陆过程中,服务器回传了包含登录凭据(类似于token)的Cookie,并保存在用户的硬盘空间上,第二次访问时,客户端会自动将该Cookie发送至服务器中,从而无须再次输入凭证,即可成功登陆。
原理
常见结构
-
来源于Amazon
其中Cookie的内部格式常以键值对的形式进行保存,可以是系统规定的,也可以添加自定义的Cookie。以下为常用的Cookie属性。
属性 | 说明 |
---|---|
NAME=VALUE | 赋予 Cookie 的名称和其值(必须项) |
expires=DATE | Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止) |
path=PATH | 将服务器上的文件目录作为 Cookie 的适用对象(若不指定则默认为文档所在的目录) |
domain=域名 | 作为 Cookie 适用对象的域名(若不指定则默认为创建 Cookie 的服务器的域名) |
Secure | 仅在 HTTPS 安全通信时才会发送 Cookie |
HttpOnly | 加以限制,使 Cookie 不能被 Javascript 脚本访问 |
缺陷
- Cookie会附加在客户端中的每一个HTTP请求,增加了传输流量。
- Cookie中HTTP中是以明文的方式进行传递(即使进行了值加密也会以加密后的内容传送),倘若保存重要数据的Cookie被窃取(XSS-跨站式脚本),会产生严重的安全性问题。
- Cookie能够发送的数量(最多20个,但通常浏览器支持会大于20个)和大小(最大为4KB)受到限制。
Session
Session(会话)是一种持久网络协议,在用户(或用户代理)端和服务器端之间的创建关联,从而起到交换数据包的作用机制。
根据上述的介绍,很难将Session与Cookie进行区别。它们两者都用共同的作用——保存用户信息,但是最本质的区别在于Cookie是保留在客户端的,而Session是保留在服务器端。然而Session的实现却需要服务器端和客户端同时实现才能发挥作用。
以下以Tomcat为容器的Web应用为例。
客户端的Session
在用户的第一次发起正常的HTTP请求时,服务器端会在请求中(通常在Cookie当中)查看是否已经存在Session标识,若不存在,服务器端将会根据自动生成Session标识(常为SessionID),并在Response中设置Cookie。若存在,服务器将使用请求中的Session标识,来标识该用户。
服务器端的Session
在之后的请求当中,客户端都会附加含有SessionID的Cookie到服务器端。服务器端将鉴别该Cookie中的SessionID,赋予该发起请求的用户。
缺陷
- 生成Session的文件是保留在内存当中。倘若服务器每天接受千万次请求,那么服务器的资源肯定会被消耗殆尽,导致服务器不可用。通常的做法是用Redis保存用户的Session,查询时直接向Redis发出请求即可。
- Session标识通常保存在Cookie当中,若浏览器禁用了Cookie,则导致服务器无法正常识别该用户。另一种可用的方式是URL重写,即直接将SessionID标识写在URL上(以QueryString的形式)
参考资料:
[1] http://www.jianshu.com/p/e143ddf6fc84
[2] http://www.jianshu.com/p/2b7c10291aad
[3] https://zh.wikipedia.org/wiki/Cookie
[4]https://zh.wikipedia.org/zh-hans/%E4%BC%9A%E8%AF%9D_)(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)