Sessions 与Cookies详解

Posted tanggula-pioneer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sessions 与Cookies详解相关的知识,希望对你有一定的参考价值。

 一、Cookie 是什么?

    HTTP协议是无状态的,每一次数据交换完毕就结束,服务器端和客户端的链接就会关闭,每次交换数据都需要建立新的链接。例如:我逛淘宝买东西,我看上了易宝棒棒糖,而我下单的时候,服务器不知道我是谁,而我有个ID,你能通过 ID 识别我,现在你居然不知道我谁?我去,那我怎么付款???

  而我们的业务是有状态的,因此,产生了 Cookie,用于记录状态 。 

  Cookie 是服务器发送到用户浏览器并保存在本地某个目录下的文本内的一小块数据,它会在浏览器之后向同一个服务器再次发起请求时被携带上。用于告知服务端两个请求是否来自同一浏览器。

  Cookie 是个存储在浏览器目录的文本文件,当浏览器运行时,存储在 RAM 中。一旦你从该网站或网络服务器退出,Cookie 也可存储在计算机的硬驱上。

二、Cookie的用途

 1. 会话状态管理(如用户登录状态、购物车、或其他需要记录的信息)。

  记录用户的登录状态是cookie最常用的用途。通常web服务器会在用户登录成功后下发一个签名来标记session的有效性,这样免去了用户多次认证和登录网站。

  记录用户的访问状态,例如导航啊,用户的注册流程啊。

 2. 个性化设置(如用户自定义设置、主题)

  Cookie 也经常用来记忆用户相关的信息,以方便用户在使用和自己相关的站点服务。

    例如:ptlogin会记忆上一次登录的用户的QQ号码,这样在下次登录的时候会默认填写好这个QQ号码。

    Cookie 也被用来记忆用户自定义的一些功能。用户在设置自定义特征的时候,仅仅是保存在用户的浏览器中,在下一次访问的时候服务器会根据用户本地的cookie来表现用户的设置。例如google将搜索设置(使用语言、每页的条数,以及打开搜索结果的方式等等)保存在一个COOKIE里。

   3. 浏览器行为跟踪(跟踪分析用户行为)

    最典型的是公司的 TCSS 系统。它使用 Cookie 来记录用户的点击流和某个产品或商业行为的操作率和流失率。当然功能可以通过IP或http header中的referrer实现,但是Cookie更精准一些。

三、Cookie是怎么被创建的?
 
过程:Cookie 是由 服务器 创建,然后通过 响应报文包含 Set-Cookie 首部字段 发送给客户端的 一个键值对。客户端得到响应报文后把 Cookie 内容保存到浏览器中,并会标注出Cookie的来源(哪个服务器的Cookie)。当 客户端 再次向 服务器 发出请求时会把所有这个浏览器保存的所有 Cookie 包含在 请求报文 中发送给服务器,这样服务器就可以识别客户端了!
 
分类

  Session Cookie---------这个类型的cookie只在会话期间内有效,即当关闭浏览器的时候,它会被浏览器删除。设置session cookie的办法是:在创建cookie不设置Expires即可。

  Persistent Cookie------持久型cookie顾名思义就是会长期在用户会话中生效。当你设置cookie的属性Max-Age为1个月的话,那么在这个月里每个相关URL的http请求中都会带有这个cookie。所以它可以记录很多用户初始化或自定义化的信息,比如什么时候第一次登录及弱登录态等。

  Secure cookie-----------安全cookie是在https访问下的cookie形态,以确保cookie在从客户端传递到Server的过程中始终加密的。这样做大大的降低的cookie内容直接暴露在黑客面前及被盗取的概率。

  HttpOnly Cookie--------目前主流的浏览器已经都支持了httponly cookie。1.IE5+ 2.Firefox 1.0+ 3.Opera 8.0+ 4.Safari/Chrome。在支持httponly的浏览器上,设置成httponly的cookie只能在http(https)请求上传递。也就是说httponly cookie对客户端脚本语言(javascript)无效,从而避免了跨站攻击时JS偷取cookie的情况。当你使用javascript在设置同样名字的cookie时,只有原来的httponly值会传送到服务器。

  3rd-party cookie--------第一方cookie是cookie种植在浏览器地址栏的域名或子域名下的。第三方cookie则是种植在不同于浏览器地址栏的域名下。例如:用户访问a.com时,在ad.google.com设置了个cookie,在访问b.com的时候,也在ad.google.com设置了一个cookie。这种场景经常出现在google adsense,阿里妈妈之类的广告服务商。广告商就可以采集用户的一些习惯和访问历史。

  Super Cookie------------超级cookie是设置公共域名前缀上的cookie。通常a.b.com的cookie可以设置在a.b.com和b.com,而不允许设置在.com上,但是很不幸的是历史上一些老版本的浏览器因为对新增后缀过滤不足导致过超级cookie的产生。

  Zombie Cookie---------僵尸cookie是指那些删不掉的,删掉会自动重建的cookie。僵尸cookie是依赖于其他的本地存储方法,例如flash的share object,html5的local storages等,当用户删除cookie后,自动从其他本地存储里读取出cookie的备份,并重新种植。

四、Cookie的实现

Cookie是通过HTTP请求和响应头在客户端和服务器端传递的,一个Cookie对象一个Set-Cookie,不同的浏览器能存储Cookie的数量不同。

cookie的几种常见属性:document.cookie="key=value;expires=失效时间;path=路径;domain=域名;secure";这些Cookie属性是不会被浏览器发送回给Server的。

  name:一个唯一确定的cookie名称。通常来讲cookie的名称是不区分大小写的。

  value:存储在cookie中的字符串值。最好为cookie的name和value进行url编码。

  expires:失效时间,表示cookie何时应该被删除的时间戳。如果不设置这个时间戳,浏览器会在页面关闭时即将删除所有cookie;不过也可以自己设置删除时间。这个值是GMT时间格式,如果客户端和服务器端时间不一致,使用expires就会存在偏差。

  path: 表示这个cookie影响到的路径,浏览器跟会根据这项配置,像指定域中匹配的路径发送cookie。  

  domain:cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息。这个值可以包含子域(如:yq.aliyun.com),也可以不包含它(如:.aliyun.com,则对于aliyun.com的所有子域都有效).-Domain 标识指定了哪些主机可以接受 Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了Domain,则一般包含子域名。例如,如果设置 Domain=mozilla.org,则 Cookie 也包含在子域名中 (如 developer.mozilla.org )。Path标识指定了主机下的哪些路径可以接受 Cookie(该URL 路径必须存在于请求 URL 中)。

  secure: 安全标志,指定后,只有在使用SSL链接时候才能发送到服务器,如果是http链接则不会传递该信息。就算设置了secure 属性也并不代表他人不能看到你机器本地保存的 cookie 信息,所以不要把重要信息放cookie就对了服务器端设置,标记为 Secure 的 Cookie 只能通过被 HTTPS 协议加密过的请求发送给服务器。但即便设置了Secure标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性,Secure 标记也无法提供确实的安全保障。  

  max-age: 与expires作用相同,用来告诉浏览器此cookie多久过期(单位是秒),而不是一个固定的时间点。正常情况下,max-age的优先级高于expires。

  HttpOnly: 标记为 HttpOnly 的 Cookie 不能被 JavaScript 脚本调用。跨站脚本攻击(XSS)常常使用 JavaScript 的document.cookie API 窃取用户的 Cookie 信息,因此使用 HttpOnly 标记可以在一定程度上避免 XSS 攻击。告知浏览器不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见。但在http请求张仍然会携带这个cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。这项设置通常在服务器端设置。

  脚本方式种植 Cookie:JavaScript或类似的寄宿在浏览器中的脚本语言也可以设置Cookie。例如JavaScript : document.cookie = “key=newvalue”;

  

浏览器相关:

  a) Cookie规范规定浏览器最少支持300个cookie,每个cookie上限为 4kb;每个域名(服务器)最少20个cookie。
  b) 浏览器都支持删除和禁用cookie
  c) 在浏览器地址栏输入:javascript:alert(document.cookie)可以看到所有cookie
  d) 默认情况下,IE浏览器仅支持设置有P3P “CP” (Compact Policy) 标记的第三方Cookie. 

 

6.Cookie窃取及会话劫持(hijacking)
相对很多Session验证方法的缺点和不足,大多数网站都是把Cookie当作用户的唯一标识。在这种情况下,黑客以可以通过窃取用户的cookie来模拟用户的请求行为,但对于服务器来说是无法辨别到底是来自用户还是黑客的。
下面给出Cookie作为用户标识的风险和安全隐患:
a. 网络监听

在网络上传输的数据都是会被监听获取的,尤其是在公共的、非加密的网络环境(free wifi)。这些数据也包括常规的http(非https加密通道)所有session,也包括HTTP 会话里的Cookie。当黑客拿到明文的cookie之后就可以模拟用户操作,比如改密码、消费等行为。
解决这个问题的最根本方法是采取https协议,通过SSL通道对内容及cookie进行加密。此外还有一些二次保护的方法可以作为过渡和折中。

b. DNS cache异常及其他     DNS域名服务器
通过DNS cache或者DNS服务商的一些漏洞问题(www.baidu.com),黑客可以通过将www.baidu.com的子域名hack.www.baidu.com指向到黑客自己的IP。这样黑客就可以通过方式http://hack.www.baidu.com/a.png图片到公共环境,从而可以获取到baidu.com下的所有cookie,包括设置了HttpOnly属性的Cookie。
解决办法:1.减少dns无效配置 2.ISP服务商加强自我安全管理。3.通过HTTPS请求对请求进行加密和授权,这样黑客很难从凭证管理中心获得认证,那么用户在操作的时候会收到明显的提示。

c. 跨站脚本XSS—窃取Cookie

由于JavaScript等脚本语言可以读取页面文档内的Cookie值,同时又可以向任意服务器发出任意的请求。综合起来,黑客可以通过脚本将当前文档下的cookie据为己有。如果黑客使用的地址是https://attacker.com/stole.cgi,那么Secure Cookie也将以明文的方式发送个attacker.com.

跨站脚本是web安全永久不变的话题。Web开发者有责任去过滤掉恶意代码。同时,HttpOnly Cookies不可以被客户端脚本读取,这就大大降低了Cookie被盗取的风险。

d. 跨站脚本XSS—hijacking
当黑客可以在www.test.com上插入一段JS脚本的话,那么没有禁用JS的用户很轻易的会收到hijacking攻击。黑客利用用户的浏览器来发出HTTP请求到test.com本身,所以与用户相关的所有cookie都会存在(包括HttpOnly和Secure Cookie)。例如:人人网发生的分享蠕虫。
对于这种攻击,除了避免跨站脚本漏洞以外,可以采取验证码的方式进行一定程度上的规避。

e. 跨站脚本XSS—代理请求
老版本的浏览器允许用户使用XMLHttpRequest发出代理请求,黑客可以通过设置代理将本地的cookie全量的发给代理服务器,再从代理服务器转发给原始服务器。当然这是很快被禁止了。
f. 跨站请求伪造—CSRF
CSRF主要是黑客将伪造的请求URL放到一个图片或者其他静态资源里,这种成本极低,且传播性和形象力非常大。
举例:Qzone的签名的修改地址是:http://qzone.qq.com/cgi-bin/modify?nick=123
那么黑客将其并放到流量很大的论坛或者博客里。那么很多人就在不知情的情况下就执行了某些操作。

7. Cookie的缺点和不足
a) 被讨论最多的就是隐私问题
b) Cookie引入的各种安全问题
c) 与REST软件架构相背离。
d) 状态不一致,后退导致cookie不会重置。
c) 过多使用到是HTTP请求流量浪费

 

Seesion----除了可以将用户的信息通过Cookie 存在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。Session 可以存储在服务器上的文件、数据库或者内存中。也可以将Session 存储在 Redis 这种内存型数据库中,效率更高。
    浏览器禁用Cookie---此时无法使用Cookie来保存用户信息,只能使用 Session。除此之外,不能再将Session ID存放到 Cookie中,而是使用 URL 重写技术,将Seesion ID作为 URL 的参数进行传递。
    Cookie与Session 选择----- 1.Cookie 只能存储ASCII码字符串中,而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选Session;
            2.Cookie存储在浏览器中,容易被恶意查看。如果非要将一些隐秘数据存在Cookie中,可以将 Cookie 值进行加密,然后在服务器进行解密。
            3.对于大型网站,如果用户所有信息都存在 Session中,那么开销是非常大的,因此不建议将所有的用户信息都存到 Session中。

 

参考笔记---https://blog.csdn.net/wang_gongzi/article/details/82733424

     https://blog.csdn.net/u014753892/article/details/52821268

     https://blog.csdn.net/zhangquan_zone/article/details/77627899

以上是关于Sessions 与Cookies详解的主要内容,如果未能解决你的问题,请参考以下文章

cookies/sessions :: 登录和注销用户的最佳方法

java网络通信:HTTP协议 之 Sessions与Cookies

Yii框架操作cookie与session的方法实例详解

Django基础学习之Cookie 和 Sessions 应用

爬虫cookies详解

Django 1.10 中文文档------3.3.8 会话sessions