Session 与 Cookie 的引入
引入:HTTP无状态协议,是指协议对于交互性场景没有记忆能力。
举例:在点击一个纯的html网页,请求获取服务器的html文件资源时,每次http请求都会返回同样的信息,因为这个是没有交互的,每一次的请求都是相互独立的。第一个请求和第二个请求也没有先后顺序,返回处理哪个,结果都是同样的资源页面,因为这种场景是无交互的,无论是什么人请求这个地址,服务器都是返回那个相同的响应。
在无交互场景中上面那样,当然也不会有太大的问题。但是对于涉及到动态交互的场景,就显得很尴尬了,何为交互?有来又有往,对于一模一样的两个接口,不同的人在请求第二个接口时可能会基于请求第一个接口的结果而有所不同。因此引入session和cookie。
Cookie
介绍session之前,我们先介绍Cookie。因为HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。因此引入Cookie,Cookie实际上是一个不超过4KB的小型的文本信息(key-value格式),它存储了用户的账号、密码等基础信息。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。
注意:Cookie具有不可跨域名性
- 很多网站都会使用Cookie。例如,Google会向客户端颁发Cookie,Baidu也会向客户端颁发Cookie。那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢?或者Google能不能修改Baidu颁发的Cookie呢?
答案是否定的。Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。
Cookie的工作原理
- 浏览器端第一次发送请求到服务器端
- 服务器端创建Cookie,该Cookie中包含用户的信息,然后将该Cookie发送到浏览器端
- 浏览器端再次访问服务器端时会携带服务器端创建的Cookie
- 服务器端通过Cookie中携带的数据区分不同的用户
cookie属性项
主要属性项 | 属性项介绍 |
---|---|
<key, value> | 键值对,可以设置要保存的 Key/Value,注意这里的 Key 不能和其他属性项的名字一样 |
Expires/Max-Age | 过期时间,在设置的某个时间点后该 Cookie 就会失效 |
Domain | 生成该 Cookie 的域名,如 domain=”www.baidu.com” |
Path | 该 Cookie 是在当前的哪个路径下生成的,如 path=/wp-admin/ |
Secure | 如果设置了这个属性,那么只会在 SSH 连接时才会回传该 Cookie |
cookie缺点
尽管 Cookie实现了服务器与浏览器的信息交互,但也存在一些缺点。
- Cookie被附加在HTTP消息中,无形中增加了数据流量。
- Cookie在HTTP消息中是明文传输的,所以安全性不高,容易被窃取。
- Cookie存储于浏览器,可以被篡改,服务器接收后必须先验证数据的合法性。
- 浏览器限制Cookie的数量和大小(通常限制为50 个,每个不超过4KB),对于复杂的存储需求来说是不够用的。
扩展
cookie并不是单纯为了实现session机制而生的。而是1993年,网景公司雇员 Lou Montulli 为了让用户在访问某网站时,进一步提高访问速度,同时也为了进一步实现个人化网络,发明了今天广泛使用的 Cookie。
cookie还用一个很广泛的用途就是记住用户的登录账号和密码,这样当用户以后再次需要登录同一个网站或系统的时候就不需要再次填写这两个字段而是直接点击“登录”按钮就好。这就相当于给了一些“甜头”给用户,这就回应了“cookie”这个词语的字面意思了。
Session
同Cookie一样,为了解决HTTP无状态问题,服务器端就为特定用户创建了特定的session,用于标示并跟踪这个用户。在PHP、ASP中,session是一种键值对的数据类型。
- Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。
- 客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
- 如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。
- Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
Session的工作原理
- 用户第一次请求服务器时,服务器端会生成一个sessionid
- 服务器端将生成的sessionid返回给客户端,通过set-cookie
- 客户端收到sessionid会将它保存在cookie中,当客户端再次访问服务端时会带上这个sessionid
- 当服务端再次接收到来自客户端的请求时,会先去检查是否存在sessionid,不存在就新建一个sessionid重复1,2的流程,如果存在就去遍历服务端的session文件,找到与这个sessionid相对应的文件,文件中的键值便是sessionid,值为当前用户的一些信息
- 此后的请求都会交换这个 Session ID,进行有状态的会话。
Session的属性项
主要属性项 | 属性项介绍 |
---|---|
<Key, Value> | 键值对,用来保存数据 |
SessionID | 获取Session编号,一般在会话开始的时候由服务器自动分配一个标识SessionId,整个会话过程中的SessionId保持不变。 |
TimeOut | 设置Session对象的超期时间,默认为20分钟。 |
Keys | 根据索引号获取Session变量值 |
Count | 获取Session变量的总数量 |
Session缺点
- Session变量和cookies是同一类型的。如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量
- 当一个用户访问某页面时,每个Session变量的运行环境便自动生成,这些Session变量可在用户离开该页面后仍保留设置的timeout分钟,所以,如果在Session中置入了较大的对象,随着站点访问量的增大,服务器将会因此而无法正常运行
- 创建Session变量有很大的随意性,可随时调用,不需要开发者做精确地处理,因此,过度使用session变量将会导致代码不可读而且不好维护。
Session和Cookie的对比
- 安全性:cookie数据存放在客户端上,安全性较差,session数据放在服务器上,安全性相对更高
- 大小限制:cookie有大小限制,单个cookie保存的数据不能超过4K,session无此限制,理论上只与服务器的内存大小有关
- 服务器资源消耗:Session是保存在服务器端上会存在一段时间才会消失,当访问增多,对服务器性能有影响
- 实现机制:Session的实现常常依赖于Cookie机制,通过Cookie机制回传SessionID