所谓HTTP cookie又称之为 web cookie或browser cookie, 在形式上是由服务端发送给用户浏览器端的一小段数据。它会自动地被浏览器存储然后在下一次请求该服务器网络资源时又返还给该服务器。由于HTTP 通信是无状态的,在登录页面设计的时候,我们往往利用cookie作为浏览器状态信息来确认当前用户是否处于登录状态。
cookies有以下三个主要应用场景:
-
Session管理 如:登录、购物车、游戏积分、或者任何由浏览器操作记录并同时应记录在服务端的数据。
-
个性设置 如:用户偏好、web 主题、其他个性化设置
-
跟踪 如:记录和分析用户习惯
cookies曾经是客户端存储数据的唯一方式,但是由于现代浏览器的普及,以及在数据量较大时,携带cookies的通信会降低网络通信的效率,越来越多的客户端信息倾向于将客户端数据存储在
localStorage和sessionStorage以及IndexedDB里。
当一个浏览器向一个服务器发送请求的时候该服务器就会在response的时候自动发送Set-Cookie header给到浏览器。
一般情况下格式如下:
Set-Cookie: key=value
Set-Cookie: key=value; Expires=<date>
Set-Cookie: key=value; Max-Age=<non-zero-digit>
Set-Cookie: key=value; Secure
Set-Cookie: key=value;; HttpOnly
cookie 类型
浏览器端cookie类型分为session cookie和permanent cookie,他们之间的区别在于前者只要在浏览器关闭后cookie就会消失,而permanent cookie则不会,二者设置的区别在于cookie设置的时候是否添加了expires或者max-age属性。
cookie 安全问题
在浏览器端,如果用户希望能够在代码层面获取cookie,可以直接调用document.cookie.
console.log(document.cookie);
但这里会有一个漏洞,一旦网络遭遇XSS 跨站攻击,恶意代码可以轻易通过document.cookie获取到当前用户cookie中的敏感信息,如userID, token等。所以在应用设计的时候,有些cookie会设置为httpOnly cookie,这样,cookie只能被服务端读取,而浏览器端获取不到任何cookie信息。所以从在这里必须强调如果是token这类的敏感信息,绝对不能存储在HTTP cookie中,因为非常容易受到劫持。原则上,cookie设置HTTPS读取是起码的规定,如果可以的话,最好放置在httpOnly cookies中。
Express cookie
尽管express原班人马后来离职创建了Koa,在国内还有阿里的egg。但是express目前来说依然是全球最大的node.js 框架,基于这个原因。我们就利用express的cookie机制来从实战角度来看cookie.
第一步由服务器设置cookie
当网络请求到达node.js服务器后,在服务器response的时候设置,代码如下:
res.cookie('key','value',{});
// 前两个参数比较好理解,也就是你要在cookie中要放入的某个键值对,第三个参数是一个可设可不设的对象,是对键值对的额外规定,比如我们在给某个cookie设置有效时间期限的时候,就需要用到他。
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
下面有一张表格详细描述了第三个参数相关配置:
| 属性 | 类型 | 描述 |
|---|---|---|
| domain | httpURL string | 默认值:本机服务器域名,一般不设置,可以设置其他服务器域名 |
| encode | function | 默认值:encodeURIComponent,一般不设置,其作用在于对于cookie值进行加密 |
| expires | Date | 如果不设置,cookies的类型则为 session cookie, 值为0. 如果设置则cookies的类型则为 permanent cookie,值得类型为GMT时间格式 |
| httpOnly | boolean | 默认值:false, 如果设置的话,那么cookie的值只有服务器可以读取,浏览器端无法读取,往往用于极其严格的token加密 |
| maxAge | number | 它的作用和expires非常相似,设置毫秒值即可,用于登录token类的设置 |
| path | string | 默认值:"/",一般不设置,一般为指定路由的cookie的设置 |
| secure | boolean | cookies只能用于https通信,在目前商业应用中,强烈建议设置 |
| signed | boolean | cookies是否被签名 |
第二步服务器清理cookie
res.clearCookie('keyname');