月度归档:2013年03月

关于Cookie

Cookie是什么

在wiki中Cookie的定义为: Cookie(复数形态Cookies),中文名称为小型文本文件或小甜饼(貌似这只是一个中文翻译,平时还是直接读的英文),指某些网站为了辨别用户身份而储存在用户本地终端上的数据。

Cookie是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器,是客户端与服务器保持会话的主要手段,其内容总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie。内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。硬盘Cookie保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。所以,按存在时间,可分为非持久Cookie和持久Cookie。

Cookie被浏览器默认发送到服务器,通过HTTP协议,请求头中以Cookie字段存储客户端的Cookie值,应答头中以Set-Cookie字段应答,当服务器需要有多个cookie字段写到客户端,则在应答头中将包含多个Set-Cookie字段。 Cookie的使用非常简单,以PHP为例,在脚本中使用setcookie函数设置对应的key,value值,通过全局变量$_COOKIE直接读取客户端发送过来的Cookie值。

Cookie简单,但是存在一些问题:

  1. 安全,明文传输内容,容易被篡改。和HTTP一样,只能说看如何使用了,看你存储的是什么了
  2. 增加网络流量,加重整个网络的负载。默认浏览器在发送请求时会将本地Cookie的内容通过Cookie字段传输到服务器。所以经常我们会独立静态图片或资源的域名,使其Cookie为空。
  3. 大小限制。各浏览器对于单个cookie的大小限制为4096个字节左右,超过大小的内容将被忽略。每个域名下可以存储有30~50个cookie,不同的浏览器,不同的版本这些值不同。为什么会有大小限制,因为cookie会默认发送,当cookie太大时,可能会导致服务器响应出错等。

Cookie的历史

1993年3月,这样一个春光明媚,面朝大海,春暖花开的时节,现在的网景公司前雇员,当时的NB的网景公司员工Lou Montulli灵光一闪,Cookie华丽丽的出生了。 Cookie第一次被正式定义是在RFC2109,嗯,这是1997年2月的一天,也许那时还有些冷。在RFC中,Cookie被称为HTTP State Management Mechanism(HTTP 状态管理机制)。  RFC2109在2000年10月被RFC2965过时,而在2011年4月,最新的刚刚火热出炉的RFC6265将RFC2965过时,可谓是长江后浪推前浪,前浪死在沙滩上。另外,RFC2964记录了使用Cookie的最佳实践。

换句话说:Cookie经过了Netscape标准、RFC2109、RFC2965和RFC26265四个标准:

  • Netscape标准:Netscape是最原始的Cookies规范,同时也是RFC2109的基础。尽管如此,还是在很多重要的方面与RFC2109不同,可能需要特定服务器才可以兼容。
  • RFC2109: RFC2109是W3C组织第一次推出的官方Cookies标准。理论上,所有使用版本Cookies的服务端都应该使用此标准。HttpClient已经将此标准设定为默认。遗憾的是,许多服务端不正确的实现了标准或者仍然使用Netscape标准。所有有时感到此标准太多于严格。
  • RFC2965:RFC2965定义了版本2并且尝试去弥补在版本1中Cookie的RFC2109标准的缺点。RFC2965是,并规定RFC2965最终取代RFC2109. 发送RFC2965标准Cookies的服务端,将会使用Set-Cookie2 header添加到Set-Cookie Header信心中,RFC2965 Cookies是区分端口的。
  • RFC6265:RFC6265主要是干掉了RFC2965,在9.3和9.4小节。另外,增加了HttpOnly字段,指定HttpOnly的Cookie不能被客户端读写,仅供HTTP传输使用,或者就服务器可以读写,浏览器作为客户端需要确保其不能读写。

Cookie和Seesion

Cookie和Session都用来保存状态信息,做会话处理,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力。 Session存储在服务器,一般通过Cookie来存储其生成的唯一ID(seesionID),当Cookie被禁用时,通常用URL回写的机制来替换Cookie。

Cookie和Session有一些不同:

  1. 存储位置的不同:Cookie将状态保存在客户端,Session将状态保存在服务器端;
  2. 与HTTP协议的关系不同:Cookie需要通过网络传输,依赖于HTTP协议,Session并没有在HTTP的协议中定 义;
  3. 可用性不同:相对于Cookie,Session在客户端禁用Cookie后还可以通过URL回写机制实现Session会话机制。
  4. 安全性不同:因为存储的位置不同,Cookie更容易被篡改,存储在服务器的Session相对来说则安全一些,客户不能随意读取这些内容,除非获到其它用户的了sessionID,这也是XSS攻击会关注的地方。

同源策略

说到WEB的安全问题就不得不提同源策略。浏览器的同源策略是 Web 安全的基础,所有的主流浏览器都会有相应的实现。同源策略中“源”是一个包含主机名、协议和端口号的三元组,则同源表示:同协议,同域名和同端口,三者都相同。同源策略的出发点是它认为自任何站点装载的信赖内容是不安全的。在同源策略的限制下,浏览器只允许网页中的脚本(如 JavaScript 或 VBScript)访问与之同源的 HTTP 请求和 Cookie。对于Cookie来说,同源策略就限制了网站间的Cookie读写操作。即使在服务器使用setcookie(PHP)函数对其它域名执行Cookie写操作也是无效的。 setcookie的域名是用来指向当前域名或根域名之类的用的,设置Cookie时,如果不指定domain的值,默认就是本域。

参考资料:

  1. http://wiki.apache.org/HttpComponents/ReferenceMaterials
  2. http://www.cnblogs.com/shepherd2012/archive/2012/08/03/2621797.html
  3. http://zh.wikipedia.org/wiki/Cookie
  4. http://curl.haxx.se/rfc/cookie_spec.html
  5. http://tools.ietf.org/html/rfc6265