Cookie & Session详解
1. Cookie#
1.1 Cookie 的基本概念及设置#
首先需要理解的是 cookie 不是任何一种语言的技术,而是独属于客户端(包括但不限于浏览器)的一种存储机制。所以说不管是 PHP 或是 JavaScript 都不能直接操作 cookie,而是通过 HTTP 协议‘通知’到浏览器,由浏览器进行操作。
同时也可以将 cookie 设置为仅 HTTP 协议才能访问(例如在 php 中的 setcookie
函数中设置 httpOnly
参数),设置之后 js 等都不能操作该 cookie。
1.2 Cookie 的存储机制应用#
cookie 没有显式的删除方式,只能通过设置过期时间的方式来删除 cookie。如果 cookie 没有设置过期时间则存储在内存中,即随着浏览器的关闭而清除。如果设置了过期时间,在过期之前 cookie 都是存储在电脑的硬盘中。
需要注意的是一个域名下 cookie 的存储数量是有限制的,根据浏览器的不同限制也不相同(例如 IE8 中可存储 50 个,火狐可存储 150 个),另外一个 cookie 的最大存储字节有限制的,限制也是由浏览器决定的。
cookie 的应用场景一般来说都是用于记住登录状态、浏览历史等这些不算敏感但能提升用户体验的东西。需要注意一点,上面提到过 cookie 与服务端的通信是基于 HTTP 的,所以 cookie 的上行下载对带宽的消耗较高。
1.3 Cookie 跨域与 P3P#
正常的 cookie 只能在创建它的应用中共享,实现 cookie 的跨域,主要是为了实现单点登录的需求。P3P 是 cookie 跨域的最简单的实现方式,具体实现方式可自行搜索,懒得写了。
2. Session#
Session 即会话,是一钟双向的、持续性的连接。Seeion 和 Cookie 在本质上并没有什么区别,都是为了解决 HTTP 协议的局限性而提出的保持客户端与服务端会话连接状态的一种机制。Session 的实现方式有多种,例如 URL 重写、Cookie,通过在 Cookie 中设置 SessionID 传递等方式。
2.1 Session 的基本概念及设置#
和 Cookie 一样 Session 也是一个通用标准,在不同的的语言中实现的方式也不同。就 web 站点的角度来讲,session 是指客户端从打开网页到关闭浏览器的这段时间的会话,所以从这里可以看出 Session 实际上一种是时间概念。Seeion 可以实现在程序上下文中传递变量、用户身份认证、记录程序状态等。
PHP 的默认 Session 由文件形式的,即保存在服务器硬盘中的文件,每个 session 一个文件,文件内容格式如下:
变量名|类型:长度:值;
2.2 Session 的工作原理#
我们知道 HTTP 协议是不能保存客户端和服务端的会话状态的,Session 和 Cookie 都是为了解决这个缺陷而被设计出来的。
在 PHP 中,Session 是通过一个叫做 PHPSESSION 的 Cookie 来保持会话的,即服务端生成一个 Session 文件存储在服务器中,这个文件的文件名就是 SessionID,服务端将这个 SessionID 设置客户端的一个名为 PHPSESSION 的 Cookie 的值,在 HTTP request 和 HTTP reponse 中传来传去,以此来实现会话状态的保持。
2.3 Session 与 Cookie 的关系#
上文说到 Session 是将 SessionID 设置为一个名叫 PHPSESSION 的 Cookie,然后在请求和响应中带上它来保持会话状态的。那么,如果客户端禁用了 Cookie 的话 Session 还能否传递?答案肯定是可以的,但是却不能通过 Cookie 的方式传递了,传递 Session 的实现的方式有很多种,例如重写 URL,如:
domain.com/index.php/SESSIONID=xxxxxxx
或者在表单中传递,还可以存储在 localStorage 中使用 JS 传递等等…
3. Q & A#
3.1 Cookie 运行在客户端,Session 运行在服务端对吗?#
不完全对。Cookie 运行在客户端,由客户端进行管理。Session 虽然运行在服务端,但是 SessionID 是作为一个 Cookie 运行在客户端的。
3.2 浏览器禁用 Cookie,Cookie 就不能用了,但 Session 不受影响对吗?#
错。浏览器禁用 Cookie,Cookie 就不能用了,同时 SessionID 也不能通过 Cookie 传递了,但可以通过其他方式传递,上文有讲。
3.3 关闭浏览器后,Cookie 和 Session 都会清除,对吗?#
错。只有存储在内存中的 Cookie 会在浏览器关闭后被清除,存储在硬盘中的不会。而 Session 在浏览器关闭后也不会消失,除非正常退出,在代码中使用 unset 删除 Session,否则 Session 可能会被回收,也可能永远残留在系统中。
3.4 Session 比 Cookie 更安全吗?不应该大量使用 Cookie 吗?#
错。Cookie 确实存在一些不安全因素,但即使突破了前端验证还有后端保障安全。在上文讲到过通常情况下 Session 和 Cookie 是绑定的,劫持了 Cookie 就等于劫持了 Session。只能说一切都要看设计。
3.5 Session 是创建在服务端的,所以应该多用 Cookie 对吗?#
错。Cookie 可以提高用户体验。但是却会加大网络间的传输流量,所以应该在 Cookie 中仅保存必要的数据。
3.6 如果把别人的 Cookie 复制到我的电脑中(相同的浏览器),是否也能登陆别人的账号呢?如何防范?#
是的。这属于 Cookie 劫持的一种。要避免这种情况可以在 Cookie 中针对 IP、UA 等加上特殊的校验方式,然后和服务端进行对比。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: