文档章节

Cookie和Session解析

二两豆腐
 二两豆腐
发布于 2015/11/24 14:52
字数 1921
阅读 40
收藏 0

   有些时候对cookiesession理解比较混乱,并且很有可能在面试的时候,也被经常提起cookiesession的区别以及使用。经过查阅一些资料,整理出以下文档

一、cookiesession的概念

1、  cookie

   当一个用户通过Http协议访问一个服务器的时候,服务器会将一些key/value这样的一些键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在相关的条件符合的情况下,浏览器再访问服务器的时候,又会把这些数据完整的带上,返回给服务器。由于HTTP协议是无状态协议,通过cookie的这种方式,服务器就能知道客户端从哪里来的。并且在一些很短的时间呢,用户的一些信息如果被频繁访问,这样服务器就可以做一些缓存等优化,保证访问的速度。

    Http协议中并没有规定相关对cookie大小等的限制,但是由于各家浏览器在实现的过程中的不同,cookie的大小也不同,但是大概为4K ,大多数浏览器对每个站点限制一般为20cookie,当超过这个数量的时候,老的cookie将会被覆盖掉。Cookie在生成的时候,会指定一个expire的值,指定cookie的过期时间,时间超过以后,此Cookie将不能再被使用。必须生成新的cookie,在我们访问网站的时候,通常会见到保存密码多长时间这个选项,如下图:

wKiom1XYla2iCv2HAACFUEIfk-s323.jpg


  实际上我们登录的这些信息被存储到了客户端浏览器中,然后通过这个cookie来保存我们个人的登录信息,这样我们在下次访问的时候就不需要再重新输入用户名和密码进行登陆。但是当超过设置的expire时间以后,就无法再使用。

  java程序中,我们可以如下代码设置和使用cookie

public String getCookie(Cookie[] cookies,String key){
      if(cookies!=null){
         for(Cookie cookie:cookies){
            if(cookie.getName().equals(key)){
                returncookie.getValue();
            }
         }
      }
      retur nnull;
 }
   publicvoiddoHello(HttpServletRequest request,HttpServletResponse response){
      Cookie[]cookies= request.getCookies();
      
      StringuserName= getCookie(cookies,"username");
      if(userName==null){
         response.addCookie(new Cookie("username","zhangsan"));
      }
      
      response.getHeader("Set-Cookie");
 }


Tomcat创建Set-cookie相应头的时序图

wKiom1XYlgGjZ-kaAAFEeCG_qQE301.jpg

   从以上时序图中我们可以看出,在我们通过response.addCooke创建多个Cookie,我们在每次创建Cookie时,都会创建一个以nameSet-CookieMimeHeaders.并且在服务器返回给客户端的时候也不会对相同Header标识的Set-Cookie进行合并。Tomcat源码中可以看出,这段代码位于org.apache.coyote.http11.Http11Processor类的prepareResponse方法中。如下:

Int size = headers.size();
for(int i=0;i<size;i++){
   outputBuffer.setHeader(headers.getName(i),headers.getValue(i));
}

   这段代码清楚的表示,在构Http返回字节流时,是将Header中的所有项顺序的写出,没有做任何修改,所以可以想象浏览器在接受HTTP协议返回的数据时是分别解析每一个Header项的。


2、  session

cookie可以让服务端程序跟踪每个客户的访问,但是每次客户端的访问都必须回传这些cookie的值,如果cookie很多,这样就无形的增加了客户端与服务端的数据量传输,而Session的出现正是为了解决这个问题。

  同一个客户端每次和服务端进行交互时,不需要每次都需要回传所有的Cookie的值,而只需要传回一个ID,这个ID是客户端在第一次访问服务端的时候生成的,而每个客户端都是唯一的,这样每一个客户端就生成了一个唯一的ID,客户端只需要传回这个ID就行了,这个ID通常是NAME为JSSIONID的一个Cookie.所以说Session通常是基于Cookie来工作的,当然当客户端禁用cookie的时候,还有其他的方式进行实现Session,但是就Session和Cookie的关系来说,Session基于Cookie进行工作。


二、session的调用过程

  有了Session ID 的服务端就可以创建HttpSession对象,第一次触发通过调用rquest.getSession()方法,如果当前的Session ID还没有对应的HttpSession对象,则会创建一个HttpSession对象。并将这个对象加到org.apache.catalina.Manager

的session容器中保存,Manager类将会管理所有Session的生命周期,Session过期将会被销毁,服务器关闭,Session将会被序列化到磁盘等。只要这个HttpSession对象存在,用户就可以根据SessionId来获取这个对象,也就达到了状态保持的问题。以下是Session创建的时序图


wKioL1XYmPbBz6_XAAMOmwjDT68943.jpg


三、cookie的安全问题

   虽然CookieSession都是可以跟踪客户端的访问记录,但是他们的工作方式显然是不同的。Cookie通过把所有要保存的数据通过HTTP西医的头部从客户端传递到服务器,又从服务器传递给客户端,所有的数据都存储到客户端的浏览器里。所以这些Cookie数据是可以被访问到的。我们通过Firefox是可以访问到记录到浏览器端的用户名和密码的。例如我的百度账号,如下图:

wKioL1XYmSTyCwzoAAG5IEmj7v4940.jpg


wKioL1XYmTPRiyz0AAFg0qa3J80637.jpg


不仅可以查看Cookie,我们甚至可以通过一些工具添加,修改Cookie,所以Cooike的安全性是不可保证的。相比较而言,Session的安全性要高很多,因为Session是将数据保存在服务端,指示通过Cookie传递一个JSESSIONID而已。所以Session更适合存储用户隐私和重要数据。

四、分布式session实现思路

    在我们应用在进行部署的时候,现在大多数情况均不是单机部署,而是进行集群的部署,但是这样会导致客户端访问的时候,如果一台服务器挂掉,这样保存在这台服务器上的session就会消失,导致客户登录等相关信息丢失,降低了客户体验的良好性。为了解决以上问题,基本上会有下面两种思路:

  • 在各台服务器间session复制共享

Session复制共享,主要指在集群环境下,各台应用服务器之间进行同步session,使得session保持一致。当一台服务器出现问题时候,负载均衡服务器会把请求负载到另外的一台服务器,由于每台服务器均存储所有服务器的session,这样可以保证请求的连续性。

但是这种方案会有以下不足

  • 技术比较复杂,必须在同一种中间件中进行实现,例如tomcat

  • Session的复制必定会带来性能上的损失,特别是当应用服务器比较多,session存储的内容比较大时。

  • Session内容的序列化,会导致服务器性能下降

  • Session通过广播或者其他形式同步到其他服务器。不管是内网还是外网,同样对网络会造成压力,使之成为瓶颈。

  • 使用session服务器,基于redis等缓存服务器

这种思想是在服务器本机存储一份session,然后再在缓存服务器中存储一份session,当服务器发生故障,在本机找不到session时,可以去缓存服务器中去寻找,再复制到本地,此种为业界常用思路。

wKioL1XYmWTSdTLOAAFSQ4qHLD0365.jpg

本文出自 “走在未来的路上” 博客,请务必保留此出处http://wtf0313.blog.51cto.com/1093061/1687219

© 著作权归作者所有

二两豆腐
粉丝 22
博文 103
码字总数 87685
作品 0
朝阳
高级程序员
私信 提问
Session和Cookies的原理及代码实现

在浏览网页时,很多页面是需要登录的,但是我们知道HTTP协议是无状态协议,那么我们在网站的各个网页间跳转时,为什么不需要重新登录账号呢?这就是Session和Cookies的功劳了,接下来,让我们...

一根薯条
2018/03/17
0
0
权限认证 cookie VS token

权限认证 cookie VS token 我前公司的应用都是 token 授权的,现公司都是维护一个 session 确认登录状态的。那么我在这掰扯掰扯这两种权限认证的方方面面。 工作流程 先说 cookie cookie 登录...

晴天_雨天
2018/02/28
0
0
Cookie-Form型CSRF防御机制的不足与反思

Cookie-Form型CSRF防御机制的不足与反思 离别歌2016-09-2650 阅读 cookieformcsrf 今天看了 https://hackerone.com/reports/26647 有感。这个漏洞很漂亮,另外让我联想到很多之前自己挖过的漏...

离别歌
2016/09/26
0
0
Laravel5.3之Session源码解析(下)

说明:在中篇中学习了session的CRUD增删改查操作,本篇主要学习关闭session的相关源码。实际上,在Laravel5.3中关闭session主要包括两个过程:保存当前URL到session介质中;在Response Head...

botkenni
2016/11/19
84
0
session、cookie、token

一、session session的中文翻译是“会话”,当用户打开某个web应用时,便与web服务器产生一次session。服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。...

满头大汉
2015/09/15
6.3K
0

没有更多内容

加载失败,请刷新页面

加载更多

崛起于Springboot2.X之5分钟解决单点登陆(53)

SpringBoot2.X心法总纲 1、pom文件依赖 <dependency> <groupId>com.majiaxueyuan</groupId> <artifactId>sso-core</artifactId> <version>1.2.2</version></dependency> 2、......

木九天
12分钟前
13
0
面向对象和面向过程的区别

面向过程 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。 缺点:没有面向对...

无名氏的程序员
13分钟前
10
0
OpenStack大事记

2010年7月19日,Rackspace、NASA、Citrix、Dell共同开发并发布OpenStack第一个版本。 2011年10月,Rackspace放弃OpenStack控制权,交由一新成立的OpenStack基金会管理。 2012年5月NASA宣布退...

大别阿郎
14分钟前
8
0
面向对象的简单应用—以交通工具(Vehicle)为列

请定义一个交通工具(Vehicle)的类其中有: 属性: 速度(speed)、 体积(size)等,方法:移动(move())、设置速度(setSpeed(int speed))、加速 speedUp()、减速 speedDown()等。最后在测试类 Ve...

INEVITABLE
25分钟前
6
0
通往艺术家之路

通往艺术家之路 并发编程中,开发者往往需要权衡锁的颗粒粗细,锁住的代码块太大呢会导致可能的线程堵塞,锁的颗粒太细呢又会因为频繁地加锁解锁导致系统用户态内核态的转换从而消费很多时间...

StupidZhe
26分钟前
21
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部