谈谈cookie

阅读 2114
收藏 158
2017-10-12
原文链接:barryliu1995.studio

今天被4399面试官问到了 cookie 的相关知识,之前不是很了解,现在补补…

什么是cookie

cookie 译为“小甜饼,具体种类称为酥性甜饼干,这是一种中档配料的产品……”。咦,跑偏了,开个玩笑先,虽然面试过程不爽,但还是得笑对人生(生无可恋)。正经说,当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,cookie 会记录如身份识别号码、密码、用户在 Web 站点购物的方式或用户访问该站点的次数等关键信息,而正因为这些信息的重要性使 cookie 技术成为广大网民和开发人员争论的一个焦点,因为 cookie 将包含但不限于上述的一些信息保存在用户浏览器上的小文本文件上,它包含有关用户的信息。这些相关信息保留下来可以为你下次再次访问该网站时鉴别用户,以便提供一些量身定做的内容。

cookie原理

第一次访问网站的时候,浏览器发出请求,服务器响应请求后,会将 cookie 放入到响应请求中,在浏览器第二次发请求的时候,会把 cookie 带过去,服务端会辨别用户身份,当然服务器也可以修改 cookie 内容(后面会谈到这点)。cookie 的产生是通过扩展 HTTP 协议来实现的,服务器通过在 HTTP 响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的 cookie。然而纯粹的客户端脚本如 JavaScript 也可以生成 cookie。而 cookie 的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的 cookie ,如果某个 cookie 所声明的作用范围(这个作用范围由 cookie 的 path 和 domain 同时决定)大于等于将要请求的资源所在的位置,则把该 cookie 附在请求资源的 HTTP 请求头上发送给服务器。

cookie属性

cookie 的属性比较多,我们可以看下下面这张图

name

这个显而易见,就是代表 cookie 的名字的意思,一个域名下绑定的 cookie ,name 不能相同,相同的 name 的值会被覆盖掉

value

这个就是每个 cookie 拥有的一个属性,它表示该属性的值

domain

这个是指的域名,这个代表的是,cookie 绑定的域名,如果没有设置,就会自动绑定到执行语句的当前域,还有值得注意的点,统一个域名下的二级域名也是不可以交换使用 cookie 的,比如,你设置 www.baidu.com 和 image.baidu.com ,依旧是不能公用的

path

path这个属性默认是/,当你设置成比如/blog的时候,其实它会给 “domain+path” 范围内绑定 cookie

Expires/Max-Age

该属性决定 cookie 的有效期,一般浏览器的 cookie 都是默认储存的,当关闭浏览器结束这个会话的时候,这个 cookie 也就会被删除,这就是上图中的—— session (会话储存)。

如果你想要 cookie 存在一段时间,那么你可以通过设置 Expires 属性为未来的一个时间节点,Expires 这个是代表当前时间的,这个属性已经逐渐被我们下面这个主人公所取代——Max-Age。

Max-Age,是以秒为单位的,Max-Age 为正数时,cookie 会在 Max-Age 秒之后被删除。在 Max-Age 之前 cookie 是保存到硬盘上,即使关闭浏览器后再次打开,这些 cookie 仍然有效直到超过设定的过期时间。存储在硬盘上的 cookie 可以在不同的浏览器进程间共享,比如两个 IE 窗口。当 Max-Age 为负数时,表示的是临时储存,不会生出 cookie 文件,只会存在浏览器内存中,且只会在打开的浏览器窗口或者子窗口有效,一旦浏览器关闭, cookie 就会消失,当 Max-Age 为 0 时,又会发生什么呢,删除 cookie ,因为cookie 机制本身没有设置删除 cookie ,失效的 cookie 会被浏览器自动从内存中删除,所以,它实现的就是让 cookie 失效。

secure

这个属性译为安全,http 不仅是无状态的,还是不安全的协议,容易被劫持。所以当这个属性设置为 true 时,此 cookie 只会在 https 和 ssl 等安全协议下传输。但需要强调一下这个属性并不能对客户端的cookie进行加密,不能保证绝对的安全性

http-only

这个属性是面试的时候常考的,如果这个属性设置为true,就不能通过js脚本来获取cookie的值,能有效的防止xss攻击,看MDN的官方文档:

关于JavaScript操作cookie

document.cookie 可以对 cookie 进行读写:

console.log(document.cookie);	//读取浏览器中的cookie
document.cookie='myname=liuzhiyu;path=/;domain=.baidu.com';	//	写入 cookie

服务端如何去设置cookie

服务端就是通过 setCookie 来设置 cookie 的,注意点,要设置多个 cookie 时,得多写几个 setCookie ,我们还可以从上图看到,请求可以携带 cookie 给后端。

cookie与session

了解 HTTP 的同学,肯定知道,HTTP 是一个不保存状态的协议,什么叫不保存状态,就是一个服务器是不清楚是不是同一个浏览器在访问他。所以要保存访问状态(信息)要么在客户端要么在服务器端。现实方案具体来说 cookie 机制采用的是在客户端保持状态的方案,而 session 机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以 session 机制可能需要借助于 cookie 机制来达到保存标识的目的,但实际上它还有其他选择。所谓服务器端采用了 session 机制,服务器使用一种类似于散列表的结构来保存信息。当服务器程序需要为某个客户端的请求创建一个 session 时,服务器首先检查这个客户端的请求里是否已包含了一个 session 标识(称为session id),如果已包含则说明以前已经为此客户端创建过 session,服务器就按照session id 把这个 session 检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个 session id 将被在本次响应中返回给客户端保存。保存这个session id 的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。一般这个cookie的名字都是类似于 SEEESIONID。但 cookie 可以被人为的禁止,则必须有其他机制以便在 cookie 被禁止时仍然能够把session id 传递回服务器。经常被使用的一种技术叫做 URL 重写,就是把 session id 直接附加在 URL 路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把 session id 传递回服务器。

  1. cookie 数据存放在客户的浏览器上,session数据放在服务器上
  2. cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗考虑到安全应当使用 session
  3. session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用 COOKIE
  4. 单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存20个 cookie。

鉴于上述区别我们建议

  1. 将登陆信息等重要信息存放为 SESSION
  2. 其他信息如果需要保留,可以放在 COOKIE 中

参考

cookie 与 session 的区别详解

把cookie聊清楚|稀土掘金

最后,如果本文有任何知识性错误,欢迎各位小哥哥小姐姐提出!


本文作者:刘志宇

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!

评论

查看更多 >