Cookie/Session
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie/Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
Cookie
Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie。内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。硬盘Cookie保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。所以,按存在时间,可分为非持久Cookie和持久Cookie
HTTP请求+Cookie的交换流程
如果步骤5携带的是过期的cookie或者是错误的cookie,那么将认证失败,返回至要求身份认证页面。
HTTP协议作为无状态协议,对于HTTP协议而言,无状态同样指每次request请求之前是相互独立的,当前请求并不会记录它的上一次请求信息。那么问题来了,既然无状态,那完成一套完整的业务逻辑,发送多次请求的情况数不胜数,使用http如何将上下文请求进行关联呢?机智的人类通过优化,找到了一种简单的方式记录http协议的请求信息
优化后的HTTP请求:
Cookie的属性
一般cookie所具有的属性,包括:
-
Domain:域,表示当前cookie所属于哪个域或子域下面。
对于服务器返回的Set-Cookie中,如果没有指定Domain的值,那么其Domain的值是默认为当前所提交的http的请求所对应的主域名的。比如访问
http://www.example.com
,返回一个cookie,没有指名domain值,那么其为值为默认的www.example.com
。 -
Path:表示cookie的所属路径。
-
Expire time/Max-age:表示了cookie的有效期。expire的值,是一个时间,过了这个时间,该cookie就失效了。或者是用max-age指定当前cookie是在多长时间之后而失效。如果服务器返回的一个cookie,没有指定其expire time,那么表明此cookie有效期只是当前的session,即是session cookie,当前session会话结束后,就过期了。对应的,当关闭(浏览器中)该页面的时候,此cookie就应该被浏览器所删除了。
-
secure:表示该cookie只能用https传输。一般用于包含认证信息的cookie,要求传输此cookie的时候,必须用https传输。
-
httponly:表示此cookie必须用于http或https传输。这意味着,浏览器脚本,比如javascript中,是不允许访问操作此cookie的。
Cookie的缺陷
- cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
- 由于在HTTP请求中的cookie是明文传递的,所以安全性成问题。(除非用HTTPS)
- Cookie的大小限制在4KB左右。对于复杂的存储需求来说是不够用的。
Session
Session的官方定义是:在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。
说白了Session就是一种可以维持服务器端的数据存储技术。Session主要有以下的这些特点:
-
Session保存的位置是在服务器端
-
Session一般来说是要配合Cookie使用,如果是浏览器禁用了Cookie功能,也就只能够使用URL重写来实现Session存储的功能
-
单纯的使用Session来维持用户状态的话,那么当同时登录的用户数量较多的时候,或者存在较多的数量的Session会导致查询慢的问题
本质上:Session技术就是一种基于后端有别于数据库的临时存储数据的技术
为什么要有Session
主要的一个原因就是HTTP的无状态性
因为HTTP的无状态性,所以我们没有办法在HTTP发送请求的时候知道当前用户的状态,也就是比如说,当前是哪个用户的之类的这种信息,所以这个时候我们需要session来标识当前的状态
Seesion的工作原理
接下来,通过一个模拟用户登录的流程图来初步理解Session的原理,假设这个时候用户执行登录操作,具体的Session工作流程如下:
整个流程大概分成这样的几步:
-
第一步将本地的Cookie中的Session标识和用户名,密码带到后台中
-
第二步后台检测有没有对应的Session标识,我们以Django为例,那么就是检测有没有接收到对应的Sessionid
-
没有的话直接生成一个新的Session。有的话,检测对应的文件是否存在并且有效
-
失效的话,我们需要清除Session然后生成新的Session。不失效,使用当前的Session
看到这里你可能对Session的工作原理有一个初步的理解
Session的原理图如下:
session的一些相关注意事项
1. 关闭浏览器session同样存在
如果我们没有人为的去设置cookie的生命周期的时候默认关闭浏览器session的状态是无法被保存下来的,因为没有设置cookie的生命周期,默认这个时候cookie为session cookie也就是在会话存在的时候cookie才有效,所以关闭浏览器cookie失效,导致后端拿不到对应的Sessionid,所以无法找到对应的session文件
2. session性能瓶颈怎样解决?
如果是后端存在大量的session的时候,那么这个时候就会出现性能的瓶颈,例如:当后端同时存在有5000个session文件的时候,假设要找的文件是在第4999个,那么也就是说前面至少需要遍历4998次,这样就会浪费过多的时间在后端的循环遍历查找文件中,所以这个时候最有效的方法是使用redis或者mongodb,原理是通过将原本保存在本地的session文件写入到内存中,通过内存换空间的形式来达到提升速度
3. 一般不使用URL重写的方法来传递Sessionid
其中主要有两个原因,一个是URL重写方式传递的话会导致URL混乱,影响美观。另一个是增大了用户误操作的几率
Cookie和Session的区别
-
存放位置不同
Cookie保存在客户端,Session保存在服务端。
-
存取方式的不同
Cookie中只能保管ASCII字符串,假如需求存取Unicode字符或者二进制数据,需求先进行编码。Cookie中也不能直接存取Java对象。若要存储略微复杂的信息,运用Cookie是比拟艰难的。
而Session中能够存取任何类型的数据,包括而不限于String、Integer、List、Map等。Session中也能够直接保管Java Bean乃至任何Java类,对象等,运用起来十分便当。能够把Session看做是一个Java容器类。
-
安全性(隐私策略)的不同
Cookie存储在浏览器中,对客户端是可见的,客户端的一些程序可能会窥探、复制以至修正Cookie中的内容。而Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的风险。 假如选用Cookie,比较好的方法是,敏感的信息如账号密码等尽量不要写到Cookie中。最好是像Google、Baidu那样将Cookie信息加密,提交到服务器后再进行解密,保证Cookie中的信息只要本人能读得懂。而假如选择Session就省事多了,反正是放在服务器上,Session里任何隐私都能够有效的保护。
-
有效期上的不同
只需要设置Cookie的过期时间属性为一个很大很大的数字,Cookie就可以在浏览器保存很长时间。 由于Session依赖于名为JSESSIONID的Cookie,而Cookie JSESSIONID的过期时间默许为–1,只需关闭了浏览器(一次会话结束),该Session就会失效。
-
对服务器造成的压力不同
Session是保管在服务器端的,每个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存。而Cookie保管在客户端,不占用服务器资源。假如并发阅读的用户十分多,Cookie是很好的选择。
-
跨域支持上的不同
Cookie支持跨域名访问,例如将domain属性设置为“.baidu.com”,则以“.baidu.com”为后缀的一切域名均能够访问该Cookie。跨域名Cookie如今被普遍用在网络中。而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。