
1.为什么需要cookie和session
1.HTTP协议无连接
无连接
HTTP每次连接只处理一个请求,服务端处理完客户端的请求,并受到客户端的应答后,就断开TCP连接
为什么无连接
HTTP协议产生于互联网,服务器需要处理面向全世界的成千上万的客户端的网页访问,每个客户端(浏览器)与服务器交换数据的间歇较大,因此如果保持这个连接,那么大多数时间都是空闲浪费的。因此HTTP的设计者将其设计为请求时建立连接,请求完毕释放连接,将资源尽快释放出以服务其他客户端。
无连接的优点和缺点
优点:释放资源,不浪费资源。
缺点:随着互联网发展,网页变得越来越复杂,网页里嵌套的东西越来越多(图片,视频等),每次访问都要重新建立一次TCP连接显得低效。
解决HTTP无连接低效的办法
Keep-Alive:使客户端和服务器的连接持续有效,当客户端对服务器发起二次三次请求时,可以避免重新建立连接。当然不可避免会带来占用资源影响性能的问题,特别当WEB服务器和应用服务器在同一台机器上运行时影响较突出。
2.HTTP协议无状态
无状态
无状态是指HTTP协议对事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,客户端给服务器发送HTTP请求后,服务器根据请求,传回数据,整个过程完成后服务器不会记录任何信息。
为什么无状态
第一,历史原因。设计HTTP最初目的就是为了提供一种发布和接收HTML页面的方法,那时候没有动态页面,只有静态HTML页面,因此不需要保持状态。
第二,跟HTTP无连接也有关系。既然HTTP完成一次请求之后就会断开TCP连接,服务器完全无法预知客户端的下一个工作,甚至不知道客户端会不会再次访问,这样保持用户的访问状态也没必要了。
第三,在满足基本功能前提下,把HTTP设计得相对简单,其实也是赋予了一种扩展能力,将一些复杂的功能扩展到以HTTP为基础的技术之上。
无状态的优点和缺点
优点:解放了服务器,每一次请求都“点到为止”,不会造成不必要的连接占用。
缺点:随着互联网发展,动态交互的WEB引用出现后,网页不再止于静态页面,人们对交互的要求越来越高,而交互又是需要承前启后的,比如一个很简单的购物车程序也是需要知道用户之前选择了什么商品。
解决保持HTTP状态的办法
Cookie和Session应运而生
2.Cookie和Session区别
-
cookie技术
客户端(浏览器)的解决方案。cookie是服务器发给客户端的特殊信息,以文本文件方式存储在客户端,当客户端每次发起请求时,会带上这些信息,标识客户端的状态。
服务器回传的cookie存放于HTTP响应头(Response Header)中,客户端发送的cookie存放在HTTP请求头(Request Header)中。
服务器接受到来自客户端浏览器的请求后,能够通过分析存放于请求头的cookie得到客户端的信息,从而动态生成相应的内容。
举例:在很多网站的登录界面有“请记住我”选项,选择之后无需再输入信息直接登录,这个就是通过cookie实现的。
格式:Set-cookie:name=name;expires=date;path=path;domain=domain
-
session技术
服务器端的解决方案。session是由服务端保存的一个数据结构,用来跟踪用户状态,这个数据可以保存在内存,数据库,文件中,通过session数据来保持HTTP状态。
客户端访问服务器时,服务器根据需要设置session,将回话信息保存,标识sessionId传递给客户端浏览器,浏览器将这个sessionId保存在内存中,也就是保存在无过期时间的cookie中,以后浏览器每次请求都会额外加上这个sessionId,浏览器根据这个sessionId,取得相应的数据信息。
3.Session建立流程
-
首次请求
浏览器首次登陆到网站服务器时,会先找到对应的cookie文件,首次访问当然没有cookie,也就是没有JSESSIONID,所以在请求头部中没有cookie的内容,请求到达服务器时,服务器一看,诶,请求头中没有JSESSIONID,那你是第一次访问哦,于是生成一个session对象,并且按照某种算法给你生成一个sessionId,并且把sessionId和session对象放入HashMap中,然后把这个sessionId发回给客户端,也就是在响应头部有一行:set-Cookie:JSESSIONID=XXXXXXXXXX,告诉你,你已经有个凭证啦,以后再来访问带着这个东西会更快哦。客户端拿到响应解析后看到,诶,给了我一个sessionId,赶紧存下来放到自己的Cookie中。
image.png
-
再次请求
比如客户端登陆后访问网站的另一个页面,也就是向同一个服务器发起了再次请求,这个时候浏览器会先检查自己有没有Cookie,这时候是由的(前提没有过期),把Cookie的内容放到请求头中,也就是请求头中有一行:set-Cookie:JSESSIONID=XXXXXXXXXX,服务器接收到请求解析后看到JSESSIONID的值也就是sessionId,根据sessionId找到对应的session,再判断该客户端有没有登陆,确认登陆后才允许访问。
image.png
4.Session数据结构
上面说了session是一种数据结构,那么到底是哪种数据结构存储了session相关的变量呢?
先来猜测一下,首先session必须被同步操作,因为在多线程环境下session是现线程间共享的,而web服务器一般情况下都是多线程的(为了提高性能还会使用线程池),其次,这个数据结构要容易操作,最好是传统的键值对的存储形式。
通过以上两点,猜测应该是ConcurrentHashMap数据结构。
然后再来验证一下,查看tomcat的源码org.apache.catalina.session. ManagerBase类里的session实例,得到验证的确是ConcurrentHashMap。
protected Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();
5.cookie和session的应用场景和其他比较
-
应用场景
Cookie的典型应用场景是Remember Me服务,即用户的账户信息通过cookie的形式保存在客户端,当用户再次请求匹配的URL的时候,账户信息会被传送到服务端,交由相应的程序完成自动登录等功能。当然也可以保存一些客户端信息,比如页面布局以及搜索历史等等。 Session的典型应用场景是用户登录某网站之后,将其登录信息放入session,在以后的每次请求中查询相应的登录信息以确保该用户合法。当然还是有购物车等等经典场景; -
安全性
cookie将信息保存在客户端,如果不进行加密的话,无疑会暴露一些隐私信息,安全性很差,一般情况下敏感信息是经过加密后存储在cookie中,但很容易就会被窃取。而session只会将信息存储在服务端,如果存储在文件或数据库中,也有被窃取的可能,只是可能性比cookie小了太多。 Session安全性方面比较突出的是存在会话劫持的问题,这是一种安全威胁,这在下文会进行更详细的说明。总体来讲,session的安全性要高于cookie; -
性能
Cookie存储在客户端,消耗的是客户端的I/O和内存,而session存储在服务端,消耗的是服务端的资源。但是session对服务器造成的压力比较集中,而cookie很好地分散了资源消耗,就这点来说,cookie是要优于session的; -
时效性
Cookie可以通过设置有效期使其较长时间内存在于客户端,而session一般只有比较短的有效期(用户主动销毁session或关闭浏览器后引发超时); -
其他
Cookie的处理在开发中没有session方便。而且cookie在客户端是有数量和大小的限制的,而session的大小却只以硬件为限制,能存储的数据无疑大了太多。
网友评论