[厉害了,我的JAVA基础](九)Session和Cookie
前言
HTTP是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。
假设要求登录认证的Web页面本身无法进行状态的管理(不记录登录的状态),那么每次跳转新页面不是要重新登录,就是要在每次请求报文中附加参数来管理登录状态。
当然,无状态协议也有它的优点。由于不必保存状态,自然可减少服务器的CPU及内存资源的消耗。从另一方面讲,也正是因为HTTP写一本身是非常简单的,所以才会被应用在各种场景中。
所以,为了解决HTTP协议无法保存状态的问题,就有了Cookie和Session的技术。
Cookie
Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态,Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端自动在请求报文中加入Cookie值后发送出去。
Cookie的典型应用有:
✈ 判断用户是否登录过网站,以便下次登录的时候能够直接登录
✈ 在HTTP请求中自动携带参数,如在实现单点登录时自动携带认证信息Token
✈ 存放暂时的信息,如在没有登录时将商品加入购物车,等登录后购物车的东西还存放着之前选择的商品。不过存放信息这个功能,HTML5中的LocalStorage现在更加流行,更加强大了。
Cookie的不足
✈ Cookie的安全性一直是一个非常大的问题,由于Cookie存储在客户端,而且是可以编辑修改的,虽然Cookie本身已经增加了一些安全性的措施,如设置Cookie的有效期,设置只读不能被JS修改等,但是仍然是可以伪造和窃取的
✈ Cookie的不可跨域名性根据Cookie的规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie而不能修改Baidu的Cookie。这样虽然在一方面保证了Cookie的安全性和便利性。但是设想一个场景,在做单点登录系统如果使用Cookie,一个网站使用的域名是taobao.com,另一个网站使用的是tianmao.com。那么这时Cookie就不能同时被携带在两个域名下,导致一个域名下在传输过程中是没有携带Cookie的,也就无法维持登录状态了。
✈ Cookie的大小限制:各个浏览器对Cookie的传输有一定的限制,在使用时要格外注意,应尽量保证Cookie个数小于20个,总大小小于4KB。由于Cookie会自动添加到HTTP的请求过程中,所以,在有的请求不会用到Cookie的时候,也会自动携带Cookie,造成了带宽的浪费,如果访问量高的话,也会浪费大量的带宽资源的
总之:Cookie虽然有不足之处,但是在网站应用中还是非常重要的,Cookie的不足之处也可以通过各种技术来尽量的解决。
Session
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器会自动生成一个Session和一个SessionID用来标识这个Session,并通过响应将SessionID发送到浏览器。客户端浏览器再次访问时将该SessionID携带上,服务器中请求中提取出SessionID,然后从Session档案中查询该客户的状态就可以了。
一般情况下,服务器会在一定时间内(默认30分钟)保存这个Session,过了时间限制,就会销毁这个Session。程序也可以根据这个SessionID保存一些其他信息到服务的Session中,如用户名密码等。
客户端保存SessionID
由于服务器端需要从Http请求中获取SessionID,所以,客户端要有提供SessionID的方法。一般浏览器提供了两种方式来保存,还有一种是程序员使用HTML隐藏域的方式自定义实现。
✈ 使用Cookie来保存,这是最常见的方法,由于Cookie能够被自动携带在HTTP请求中,所以无需对这个SessionID进行管理,但是要保证Cookie的有效期和服务端Session的有效期的合理性,不然Cookie提前失效了,服务器就不能获取到Cookie了。如果浏览器禁用Cookie,那么就使用URL重写以采用第二种方式。
✈ 使用URL附加信息的方式,就像我们经常看到的网站会有:aaa.jsp?JSESSIONID=×××××××;一样的,
✈ 在页面表单里面增加隐藏域
在JAVA中sessionid如何产生?由谁产生?保存在哪里?请看下面这篇博客:
https://www.cnblogs.com/woshimrf/p/5317776.html
Session存放在服务端的问题:
- 如果访问量大的话,存放在服务器的Session数据过多,会占用大量的服务器内存资源
- 如果分布式部署应用,会导致Session存储在不同服务器上,需要做Session同步
Session和Cookie的区别
这个问题也是面试中经常问到的问题,那么我们总结一下:
➤ Cookie存放在客户端即浏览器,Session存放在服务端即服务器
➤ Cookie不是很安全,存放在本地的Cookie可以被获取并篡改和欺骗,Session存储在服务器端,相对安全
➤ Cookie中如果设置了路径参数,那么同一网站中不同路径下的Cookie不能互相访问;Session不能区分路径,同一个用户访问一个网站期间,所有的session在任何一个地方都可以访问到
➤ session会在一定时间内保存在服务器上,当访问增多,会占用服务器性能,考虑减轻服务器性能方面,应当使用cookie
➤ 单个cookie保存的数据不能超过4K,很多浏览器限制一个站点最多保存20个cookie
参考:
《图解HTTP》
吐血推荐下面的这个博客,讲解的非常详细:
https://www.cnblogs.com/andy-zhou/p/5360107.html#_caption_0