跳到主要内容

Session 和 Cookie 的概念

现在正式进入第四部分学习,作为开头部分,我们首先要介绍下 Web 框架中常用到的 Cookie 和 Session 的概念。在了解了这些基础知识后,我们就可以学习 Django 中是如何使用 Cookie 和 Session 帮我们完成一些简单的必要功能。话不多说,现在就开始吧!

1. 为什么需要Cookie和Session?

在 Web 程序中,对会话的跟踪是很一件非常重要的事情。通常,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能互不干扰。然而大部分的 Web 应用程序都是使用HTTP 协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。如果 Web 服务上没有这种的会话追踪功能,那么大部分网站都会陷入一片混乱。特别是对于电商网站而言,如果我添加一次购物车就需要登录一次确认身份,那对于用户体验而言是糟糕透的。会话(Session)跟踪是 Web 程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份Session通过在服务器端记录信息确定用户身份。正是有了 Cookie 和 Session 这样的会话跟踪技术,弥补了 HTTP 协议无状态的不足,才使得我们可以无差别的访问网站,即只需要一次登录,后续所有的操作通过 Cookie 或者 Session 便能自动识别为该用户,并维持在一个会话中。

2.1 什么是Cookie?

前面已经介绍了,Cookie 是一种会话跟踪技术,且将用户信息记录在客户端,通常是我们自己电脑上的某个位置,这个位置是固定的,和使用的浏览器有关。目前Cookie已经成为标准,所有的主流浏览器如 IE、Netscape、Firefox、Opera 以及 Chrome 等都是支持 Cookie 的。

Cookie 实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个 Cookie。客户端浏览器会把 Cookie 保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该 Cookie 一同提交给服务器。服务器检查该 Cookie,以此来辨认用户状态。服务器还可以根据需要修改 Cookie 的内容。

现在我们访问下慕课网,然后进行登录,登录之后我们所有在慕课网中的操作都会带上这个 Cookie 去请求后端服务,这样后端服务通过 Cookie 就能识别请求的用户。参考下面两个图,第二个是 Cookie 的真实位置,它是放到请求头部中的,具体内容是用逗号分隔的 key=value 形式。

图片描述

图片描述

此外, 我们在前端调试工具页面中选择 Console Tab 页面,输入一行 js 代码就能拿到对方网站发给我们的 cookie值:

图片描述

2.2 Cookie的特点

Cookie 有如下特点:

不可跨域名性

这个是 Cookie 非常重要的一个特点,域名限制。表示 A 网站颁发的 Cookie 在用户访问 B 网站时并不会被提交到 B 网站上去,这些都是由 Cookie 规范确定。此外,W3C 标准还禁止了 JavaScript 读写任何不属于自己网站的 Cookie;

时间限制

Cookie 同样有着自己的生命周期,其 maxAge 值决定着 Cookie 的有效期,单位为秒。如果maxAge 属性为正,则表示该 Cookie 会在 maxAge 秒之后自动失效。浏览器会将 maxAge 为正数的 Cookie持久化,即写到对应的 Cookie 文件中。无论客户关闭了浏览器还是电脑,只要还在 maxAge 秒之前,登录网站时该 Cookie 仍然有效;如果 maxAge 为负数,则表示该 Cookie 仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该 Cookie 即失效。maxAge 为负数的 Cookie,为临时性 Cookie,不会被持久化,不会被写到 Cookie 文件中。Cookie 信息保存在浏览器内存中,因此关闭浏览器该 Cookie 就消失了。Cookie 默认的 maxAge 值为–1;而如果 maxAge 为0,则表示删除该 Cookie。Cookie 机制没有提供删除 Cookie 的方法,因此通过设置该 Cookie 即时失效实现删除 Cookie 的效果。失效的 Cookie 会被浏览器从 Cookie 文件或者内存中删除;

  • 空间限制:Cookie 只能存储4-10KB;
  • 数量限制:一般而言,每个域下最多不能超过50个 Cookie
  • 存储数据类型限制:Cookie只能存储字符串

从上面这些特点,我们也能发现使用 Cookie 的一些缺点。使用 Cookie 最大的问题就是安全性,因为 Cookie 是保存在客户端的,且每次发送 HTTP 请求都会将 Cookie 带过去。这些都导致 Cookie 很容易泄露出去,如果一旦 Cookie 泄露,且 Cookie 中设置的时间较长,那么很可能攻击者拿着这个 Cookie 就能冒充受害者的身份去做一些事情,最后留下的记录都是受害者的。然而接下来的 Session 在某种程度上避免了这一类的问题。

3. Session

3.1 什么是Session?

Session 是另一种记录客户状态的机制,不同于 Cookie 保存在客户端浏览器中,Session 数据时保存在服务器上。浏览器访问服务器的时,服务器会把客户端信息以某种形式记录在服务器上,这些数据就是 Session。客户端浏览器再次访问时只需要从该 Session 中查找该客户的状态就可以了。

Cookie 机制是通过检查客户身上的“通行证”来确定客户身份,Session 机制是通过检查服务器上的“客户明细表”来确认客户身份。Session 相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

当多个客户端执行程序时,服务器会保存多个客户端的 Session。获取 Session 的时候也不需要声明获取谁的Session。Session 机制决定了当前客户只会获取到自己的 Session,而不会获取到别人的 Session。各客户的Session 也彼此独立,互不可见

Session 的使用虽然比 Cookie 方便许多,但是过多的 Session 存储在服务器内存中,会对服务器造成压力。

3.2 Session的生命周期

这里我们谈谈 Session 的生命周期,和 Cookie 有所不同。首先 Session 保存在服务器端,为了获得更高的存取速度,服务器一般把Session放在内存里。Session 会在用户第一次访问服务器的时候自动创建。Session 生成后,只要用户继续访问,服务器就会更新 Session 的最后访问时间,并维护该 Session。用户每访问服务器一次,无论是否读写 Session,服务器都认为该用户的 Session “活跃”了一次。

由于会有越来越多的用户访问服务器,因此 Session 也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的 Session 从内存删除。这个时间就是 Session 的超时时间。如果超过了超时时间没访问过服务器,Session 就自动失效了。

介绍完了 Cookie 和 Session 之后,我们现在来看看二者的区别,当然最大的区别前面已经反复强调过了:

  • Cookie 数据存放在客户的浏览器上,Session 数据放在服务器上
  • 上面的区别也导致了 Cookie 和 Session 之间安全性的差别。Cookie 数据保存在用户端,数据容易被窃取,不太安全。虽然对 Cookie 中的敏感信息加密可以暂时规避安全风险,但即使加密数据被泄露了总归是不好的;Session 数据存储在服务器,可以有效规避信息泄露问题;
  • Cookie 和 Session 之间生命周期不同,具体可以看前面两个的介绍;
  • 单个 Cookie 保存的数据不能超过4K,很多浏览器都会限制一个站点最多保存20个 Cookie,且只能保存字符串内容;对于 Session 则没多少限制,Session 可以保存复杂的数据类型,而且数量没有限制,主要是访问用户太多后,容易造成服务器内存溢出。

4. 小结

本小节中我们详细介绍了 Cookie 和 Session 中的一些基本概念以及各自的优缺点。在了解了这些基础知识后,我们就可以在 Django 中操作 Cookie 和 Session 了。