Cookie和Session的区别及工作原理

本文详细分析了Cookie和Session的区别及工作原理,并对Cookie和Session安全性进行了对比。

Session和Cookie在网站开发中是用来保存用户与后端服务器的交互状态。

它们有各自的缺点和优点,而且他们的优点和应用场景是对立的。

什么是Cookie?

cookie:当一个用户通过HTTP访问一个服务器时,这个服务器会将一些Key/Value键值返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时,用户下次访问这个服务器时,数据又将完整地带回给服务器。

简短版描述:Cookie就像是访问服务器时服务器颁发给用户的“身份证”,下次访问的时候带回这身份证,服务器就能识别信息。

版本:当前的Cookie有两种版本,Version 0 和Version 1,它们分别对应两种设置相应头的标识,分别是“Set-Cookie”和“Set-Cookie2”。两种版本的属性项有些不一样。值得注意的是:Java Web的Servlet并不支持Set-Cookie2响应头,在实际应用中,Set-Cookie2的一些属性项可以设置在Set-Cookie中。

Cookie是如何工作的?

真正创建Cookie是在org.apache.catalina.connector.Response类中完成的,调用generateCookieString方法将Cookie对象构造成一个字符串,构造的字符串的格式如userName=”junshan”;Version=”1″;Max-Age=1000.然后将这个字符串命名为Set-Cookie添加到MimeHeaders中。值得注意的是:Cookie对象的名字不能和Header的项重复,不然将导致错误。

我们在创建Cookie时,都创建了一个以NAME为Set-Cookie的MimeHeaders。每次调用addCookie时,都会创建一个Header。同时,在HTTP返回字符流时,是将Header中的所有项顺序地写入,而没有经过任何地修改。所以浏览器在接受HTTP返回的数据时是分别解析Header项的。

当我们请求某个URL路径时,浏览器会根据这个URL将符合条件的Cookie放在Request请求头中传回服务器,服务器通过request.getCookies()来获取所有的Cookie。

使用Cookie的注意事项

1、如果不为Cookie设置它的生存周期的话,默认是关闭浏览器的时候就销毁Cookie。

2、Cookie默认情况下是不允许出现中文字符的,如果我们要添加具有中文内容的Cookie时,我们需要使用java.net.URLEncoder先对中文进行编码,随后在进行Cookie的添加。读取Cookie时,需要使用java.net.URLDecoder对其进行解码。

3、不同的浏览器对Cookie的存储都有一些限制,通常是Cookie数量和Cookie总大小的限制。像火狐对Cookie的限制是每个域名只能有50个Cookie值,总大小不能超过4097个字。

4、Cookie在HTTP的头部,所以通常的gzip和deflate针对HTTP Body的压缩不能压缩Cookie,如果Cookie的量非常大,要做Cookie做压缩,压缩方法是将Cookie的多个K/V看作是普通的文本,做文本压缩。值得注意的是,Cookie的规范中规定,Cookie仅能保存ASCII码为34~126的可见字符,所以压缩之后的结果再进行转码,可以进行Base32或者Base64编码。

Session

完整描述:从客户端浏览器连接服务器开始,到客户端浏览器与服务器断开为止,像这样的一次会话中,Session起到的作用是跟踪用户的会话信息。

简短版描述:Session在浏览器和服务器连接过程中跟踪用户信息。

Session是如何工作的?

服务器创建HttpSession对象的前提是拥有Session ID。第一次触发通过request.getSession()方法。当当前的Seesion ID还没有相应的HttpSession对象时,服务器会创建一个新的,并将这个对象加到org.apache.catalina.Manager的session容器中保存。

Manager类将管理所有Session的生命周期,Session过期就会被回收,服务器关闭,Session将被序列化到磁盘等。

只要这个HttpSession对象存在,用户就可以根据Session ID来获取这个对象,也就做到了对状态的保持。

从Request中获得的Session对象保存在org.apache.catalina.Manager类中,它的实现类是StandardManager,通过requestedSessionId从StandardManager的session集合中取出SandardSession对象。一个客户端对应一个StandardSession对象,这个对象正是保存着我们创建的Session值。

当Servelt容器重启或者关闭的时候,StandardManager负责持久化没有过期的StandardSession对象,它将所有的StandardSession对象持久化到“SESSIONS.ser”为文件名的文件中,到Servlet重启的时候,它会重新读取这个文件,解析出所有的Session对象,并重新保存在session集合中。

说明:

session范围内的属性可以在多个页面的跳转之间共享。一旦关闭浏览器,即session结束,session范围内的属性将全部失去。

session对象是HttpSession的实例,它有两个常见的方法:getAttribute()和setAttribute()。

session的属性值可以是任何可序列化的java对象。

Cookie和Session安全性对比

Cookie:数据保存在客户端的中,所有这些数据可以被访问到的,甚至可以人为地进行修改和添加,所以在这方面的话,Cookie是不安全的。

Session:数据保存在服务器端,只是通过Cookie传递一个SessionID而已,所以Session更适合用来存储用户私密和重要信息。如登陆密码等。

安全性解决方案:

分布式Session框架

使用Cookie可以很好地解决应用的分布式部署问题,由于Cookie是将值存储在客户端的浏览器里,用户每次访问都会将最新的值带回到处理该请求的服务器,所以不存在同一个用户的请求会在同一台服务器处理而导致Cookie不一致的问题。

但是,过多的使用Cookie也会造成一些麻烦:如客户端的限制、Cookie管理混乱、安全令人担忧等。

于是,分布式Session框架诞生。

统一使用订阅服务器推送配置可以有效地集中管理资源,所以省去了每个应用都来配置Cookie,简化Cookie的管理。用统一的一个服务订阅服务器,在应用启动的时候从该服务器订阅这个应用能够使用哪些Session和Cookie项,这些配置的Session和Cookie可以限制这个应用能够使用哪些Session和Cookie,甚至控制Session和Cookie可读或者可写。这样就可以精确地控制哪些应用可以操作哪些Session和Cookie,从而有效地控制Session的安全性和Cookie的数量。

还有一个非常重要的问题是:如何处理跨域名来共享Cookie的问题。Cookie是有域名限制的,一个域名下的Cookie不能再另外一个域名下访问,如果要在两个域名之间实现登陆有效,需要实现Session同步,需要另外一个跳转应用,这个应用可以被一个或多个域名访问。 它的主要功能是从一个域名下取得sessionID,然后将这个sessionID同步到另外一个域名下。这个sessionID其实就是一个Cookie,相当于JSESSIONID,所以,经过12步的操作,一个域名不用登陆就可以取到另外一个域名下的session。

125jz网原创文章。发布者:江山如画,转载请注明出处:http://www.125jz.com/4887.html

(0)
江山如画的头像江山如画管理团队
上一篇 2020年2月11日 下午12:01
下一篇 2020年2月11日 下午12:18

99%的人还看了以下文章

  • MySQL存储过程快速入门

    什么是存储过程 创建一个简单的存储过程 存储过程中的参数 存储过程的优势和不足 一、什么是存储过程 存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。 一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。 存储过程就是一组SQL语句集,功能强大,可以实现一些比较复杂的逻辑功能 MySQL…

    2018年12月20日
    2.9K0
  • 简!python中安装pip的方法

     pip的安装 打开cmd,输入以下命令安装pip: python -m ensurepip –default-pip 出现如下图所示,代表pip安装成功: 查看pip版本 pip –version 更新pip版本 python -m pip install –upgrade pip 安装库 例如安装pyyaml库,打开cmd输入以下命令: pip i…

    2023年5月18日
    4.8K0
  • 如何设计单元测试用例,单元测试快速入门教程四

    测试人员在实际工作中根据不同覆盖要求设计面向代码的单元测试用例,运行测试用例后至少应实现如下覆盖需求: 对程序模块的所有独立的执行路径至少覆盖一次; 对所有的逻辑判定,真假两种情况至少覆盖一次; 在循环的边界和运行界限内执行循环体; 测试内部数据结构的有效性等。 至少应设计覆盖如下需求的基于功能的单元测试用例: 测试程序单元的功能是否实现; 测试程序单元性能…

    2018年4月18日
    4.3K0
  • python 实战-逢7 过游戏的实现

    不知道你有没有玩过“逢 7 过”的游戏,游戏规则很简单: 几个人轮流报数,凡遇到 7 的倍数,或含 7 的数字就要跳过,否则就算失败。 今天我们就用 Python 来打印 1 到 100 之间,所有满足条件的数字。 知识点 Python 开发环境 int 类型 变量 运算符 while 循环 条件判断 💡提示: 开发中,我们经常要先构思框架,…

    2022年2月2日
    4.7K0
  • python 循环语句的应用:水仙花数判断及爱因斯坦阶梯编程

    一、水仙花数判断程序 1.任务内容: 水仙花数是一个三位整数,如153是一个水仙花数,是因为该数的百位的立方、十位的立方、个位的立方和等于该数本身,如下所示: 2.程序编写要求: 使用for语句完成; 统计水仙花数个数的值保存到变量中,要求自动进行统计 •输出结果如下所示: 153 是水仙数370 是水仙数371 是水仙数407 是水仙数三位数中有4个水仙数…

    2022年5月11日
    3.2K1
  • 上机四 数据库访问技术

    2学时 一、数据库编程案例:读取数据库信息并显示 数据库员工信息表字段如下: 使用JDBC连接数据库,读取employee表中信息并显示到页面。 mysql驱动下载:mysql-connector-java-5.1.41-bin.zip 注意事项:将驱动程序mysql-connector-java-5.1.6-bin,拷贝到Web应用程序的WEB-INF\l…

    2018年10月16日 编程开发
    5.5K0

发表回复

登录后才能评论