前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【知识】深入理解COOKIE&SESSION的原理和区别

【知识】深入理解COOKIE&SESSION的原理和区别

作者头像
辉哥
发布2022-05-13 14:09:10
2.1K0
发布2022-05-13 14:09:10
举报
文章被收录于专栏:区块链入门

1. 摘要

本文介绍cookie知识,session知识,双方的区别,以及如何使用cookie和session实现一次会话的知识。

2. 内容

2.1 COOKIE

2.1.1 什么是Cookie?

Cookie 是一些数据, 存储于你电脑上的文本文件中。 当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。 Cookie 的作用就是用于解决 "如何记录客户端的用户信息": 当用户访问 web 页面时,他的名字可以记录在 cookie 中。 在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。 Cookie 以名/值对形式存储,如下所示:

username=John Doe

当浏览器从服务器上请求 web 页面时, 属于该页面的 cookie 会被添加到该请求中。服务端通过这种方式来获取用户的信息。 打个比方,我们去银行办理储蓄业务,第一次给你办了张银行卡,里面存放了身份证、密码、手机等个人信息。当你下次再来这个银行时,银行机器能识别你的卡,从而能够直接办理业务。

2.1.2 Cookie的工作原理

当用户第一次访问并登陆一个网站的时候,cookie的设置以及发送会经历以下4个步骤: (1)客户端发送一个请求到服务器 (2)服务器发送一个HttpResponse响应到客户端,其中包含Set-Cookie的头部 (3)客户端保存cookie,之后向服务器发送请求时,HttpRequest请求中会包含一个Cookie的头部 (4)服务器返回响应数据

为了探究这个过程,写了代码进行测试,如下:

我在doGet方法中,new了一个Cookie对象并将其加入到了HttpResponse对象中

代码语言:javascript
复制
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
        // 设置生命周期为MAX_VALUE
        cookie.setMaxAge(Integer.MAX_VALUE);
        resp.addCookie(cookie);
    }

浏览器输入地址进行访问,结果如图所示:

可见Response Headers中包含Set-Cookie头部,而Request Headers中包含了Cookie头部。name和value正是上述设置的。

2.1.3 cookie属性介绍

2.1.3.1 cookie属性项

属性项

属性项介绍

NAME=VALUE

键值对,可以设置要保存的 Key/Value,注意这里的 NAME 不能和其他属性项的名字一样

Expires

过期时间,在设置的某个时间点后该 Cookie 就会失效

Domain

生成该 Cookie 的域名,如 domain="www.baidu.com"

Path

该 Cookie 是在当前的哪个路径下生成的,如 path=/wp-admin/

Secure

如果设置了这个属性,那么只会在 HTTPS/SSL连接时才会回传该 Cookie

2.1.3.2 Expires

该属性用来设置Cookie的有效期。Cookie中的maxAge用来表示该属性,单位为秒。Cookie中通过getMaxAge()和setMaxAge(int maxAge)来读写该属性。maxAge有3种值,分别为正数,负数和0。

如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中(每个浏览器存储的位置不一致)。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。

代码语言:javascript
复制
        Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
        // 设置生命周期为MAX_VALUE,永久有效
        cookie.setMaxAge(Integer.MAX_VALUE);
        resp.addCookie(cookie);

当maxAge属性为负数,则表示该Cookie只是一个临时Cookie,不会被持久化,仅在本浏览器窗口或者本窗口打开的子窗口中有效,关闭浏览器后该Cookie立即失效。

代码语言:javascript
复制
        Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
        // MaxAge为负数,是一个临时Cookie,不会持久化
        cookie.setMaxAge(-1);
        resp.addCookie(cookie);

可以看到,当MaxAge为-1时,时间已经过期

image

当maxAge为0时,表示立即删除Cookie

代码语言:javascript
复制
        Cookie[] cookies = req.getCookies();
        Cookie cookie = null;

        // get Cookie
        for (Cookie ck : cookies) {

            if ("mcrwayfun".equals(ck.getName())) {
                cookie = ck;
                break;
            }
        }

        if (null != cookie) {
            // 删除一个cookie
            cookie.setMaxAge(0);
            resp.addCookie(cookie);
        }

那么maxAge设置为负值和0到底有什么区别呢?

maxAge设置为0表示立即删除该Cookie,如果在debug的模式下,执行上述方法,可以看见cookie立即被删除了。

image

maxAge设置为负数,能看到Expires属性改变了,但Cookie仍然会存在一段时间直到关闭浏览器或者重新打开浏览器。

image

2.1.3.3 修改或者删除Cookie

HttpServletResponse提供的Cookie操作只有一个addCookie(Cookie cookie),所以想要修改Cookie只能使用一个同名的Cookie来覆盖原先的Cookie。如果要删除某个Cookie,则只需要新建一个同名的Cookie,并将maxAge设置为0,并覆盖原来的Cookie即可。

新建的Cookie,除了value、maxAge之外的属性,比如name、path、domain都必须与原来的一致才能达到修改或者删除的效果。否则,浏览器将视为两个不同的Cookie不予覆盖。

值得注意的是,从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name和value属性,maxAge属性只被浏览器用来判断Cookie是否过期,而不能用服务端来判断。

image

我们无法在服务端通过cookie.getMaxAge()来判断该cookie是否过期,maxAge只是一个只读属性,值永远为-1。当cookie过期时,浏览器在与后台交互时会自动筛选过期cookie,过期了的cookie就不会被携带了。

2.1.3.4 Cookie的域名

Cookie是不可以跨域名的,隐私安全机制禁止网站非法获取其他网站的Cookie。

正常情况下,同一个一级域名下的两个二级域名也不能交互使用Cookie,比如test1.mcrwayfun.com和test2.mcrwayfun.com,因为二者的域名不完全相同。如果想要mcrwayfun.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数为.mcrwayfun.com,这样使用test1.mcrwayfun.com和test2.mcrwayfun.com就能访问同一个cookie

一级域名又称为顶级域名,一般由字符串+后缀组成。熟悉的一级域名有baidu.com,qq.com。com,cn,net等均是常见的后缀。 二级域名是在一级域名下衍生的,比如有个一级域名为mcrfun.com,则blog.mcrfun.comwww.mcrfun.com均是其衍生出来的二级域名。

如果我希望一级域名相同的网页之间的Cookie之间可以互相访问,需要使用到domain方法

代码语言:javascript
复制
 Cookie cookie = new Cookie("name","admin");
  cookie.setMaxAge(1000);
  cookie.setDomain(".ideal.com);
  response.addCookie(cookie);
  printWriter.writer("使用www.ideal.com域名添加了一个Cookie,只要一级域名是ideal.com即可访问")
2.1.3.5 Cookie的路径

path属性决定允许访问Cookie的路径。比如,设置为"/"表示允许所有路径都可以使用Cookie. 一般来说,Cookie发布出来,整个网页的资源都可以使用,但是如果只需要某一个Servlet可以获取到Cookie,其他的资源不能或不需要获取。

代码语言:javascript
复制
  Cookie cookie = new Cookie("name","admin");
  cookie.setPath("/Servlet);
  cookie.setMaxAge(1000);
  response.addCookie(cookie);
  printWriter.writer("该Cookie只能在Servlet1中可以访问到")
2.1.3.6 Cookie的安全属性

HTTP协议不仅是无状态的,而且是不安全的!如果不希望Cookie在非安全协议中传输,可以设置Cookie的secure属性为true,浏览器只会在HTTPS和SSL等安全协议中传输该Cookie

设置secure属性不会将Cookie的内容加密,如果想保证安全,最好使用md5算法加密。

2.1.4 cookie规范

  • Cookie大小上限为4KB;
  • 一个服务器最多在客户端浏览器上保存20个Cookie;
  • 一个浏览器最多保存300个Cookie

上面的数据是HTTP对Cookie的规范,但是现在一些浏览器可能会对Cookie规范 做了一些扩展,例如每个Cookie的大小为8KB,最多可保存500个Cookie等 不同的浏览器之间是不共享Cookie的

2.1.5cookie 常用函数

代码语言:javascript
复制
 //用于在其响应头中增加一个相应的Set-Cookie头字段
  addCookie
  
  //用于获取客户端提交的Cookie
  GetCookie
  public Cookie(String name,String value)
      
  //该方法设置与 cookie 关联的值。
  setValue
  
  //该方法获取与 cookie 关联的值。
  getValue
  
  //该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie只会在当前 session 会话中持续有效。
  setMaxAge
  
  //该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭
  getMaxAge
  
  //该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。
  setPath
  
  //该方法获取 cookie 适用的路径。
  getPath
  
  //该方法设置 cookie 适用的域
  setDomain
  
  //该方法获取 cookie 适用的域
  getDomain

2.2 SESSION

2.2.1 什么是SESSION?

Session是另一种记录浏览器状态的机制,Cookie保存在浏览器中,Session保存在服务器中。用户使用浏览器访问服务器的时候,服务把用户的信息,以某种形式记录在服务器,这就是Session。

为何使用Session因为Session可以存储对象,可以解决很多Cookie解决不了的问题,而Cookie只能存储字符串。

2.2.2 函数

Session有着request和ServletContext类似的方法。其实Session也是一个域对象。Session作为一种记录浏览器状态的机制,只要Session对象没有被销毁,Servlet之间就可以通过Session对象实现通讯。

代码语言:javascript
复制
  //获取Session被创建时间
  long getCreationTime()
  
  //获取Session的id
  String getId()
  
  //返回Session最后活跃的时间
  long getLastAccessedTime()
  
  //获取ServletContext对象
  ServletContext getServletContext()
  
  //设置Session超时时间
  void setMaxInactiveInterval(int var1)
  
  //获取Session超时时间
  int getMaxInactiveInterval()
  
  //获取Session属性
  Object getAttribute(String var1)
  
  //获取Session所有的属性名
  Enumeration getAttributeNames()
  
  //设置Session属性
  void setAttribute(String var1, Object var2)
  
  //移除Session属性
  void removeAttribute(String var1)
  
  //销毁该Session
  void invalidate()
  
  //该Session是否为新的
  boolean isNew()

2.3 COOKIE和SESSION的区别和联系

2.3.1 COOKIE和SESSION的区别

1. 从存储方式上比较

Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码。 Session可以存储任何类型的数据,可以把Session看成是一个容器

2. 从隐私安全上比较

Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密。 Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题。

3. 从有效期上比较

Cookie保存在硬盘中,只需要设置maxAge属性为比较大的正整数,即使关闭浏览器,Cookie还是存在的。 Session的保存在服务器中,设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但也就失效了。

4. 从对服务器的负担比较

Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。 Cookie是保存在客户端的。不占用服务器的资源。像baidu、Sina这样的大型网站,一般都是使用Cookie来进行会话跟踪。

5. 从浏览器的支持上比较

如果浏览器禁用了Cookie,那么Cookie是无用的了! 如果浏览器禁用了Cookie,Session可以通过URL地址重写来进行会话跟踪。

6. 从跨域名上比较

Cookie可以设置domain属性来实现跨域名 Session只在当前的域名内有效,不可跨域名

2.3.2 COOKIE和SESSION实现会话跟踪

我们用浏览器登录网站,访问网站页面,是通过超文本传输协议(HTTP),将web服务器的超文本标记语言(HTML)文档传送到客户端的浏览器供用户浏览的。登录网站到退出网站,作为一次会话,数据交换完毕,客户端与服务器端的连接就关闭,但是HTTP协议是无状态协议,如果要再次交换数据,就需要重新登录网站,建立新的连接,这就意味着用户上次访问的所有信息(比如登录的用户信息、精选的商品等)都归零。

为了改善用户体验,跟踪用户的会话,就要用到会话跟踪技术,而常用的跟踪技术就有Cookie和Session。

2.3.2.1 Cookie实现会话跟踪

Cookie是网页浏览器用来保存用户信息的文件,位于用户的计算机上,比如登录某个网页输入的用户名和密码,如果被保存为cookie记录,下次打开页面,cookie记录会一起发送给web服务器直接识别用户信息,不需要用户手动登录了。

cookie使用示意图

  • 首先浏览器发送一个HTTP请求到服务器端;
  • 服务器返回一个HTTP响应给客户端,包括Set-Cookie,要求浏览器建立cookie用来保存服务器指定的内容(比如用户信息);
  • 下一次访问网站时候,浏览器发送HTTP请求到服务器,并将保存好的cookie一起发送给服务器;
  • 服务器收到cookie并识别出用户信息,就可以专门为用户提供响应内容。

2.3.2.2 Session实现会话跟踪

Session称为会话信息,位于web服务器上,是一种记录客户状态的机制,用户浏览器访问服务器时,服务器把用户信息以某种形式记录下来,当用户再次访问时,服务器从Session中查找用户状态。

session使用示意图

  • 首次访问时,浏览器发送一个HTTP请求到服务器端;
  • 服务器需要给客户端请求创建session时,检查客户端请求里是否包含sessionID,如果客户端请求没有ID,服务器为客户端建立一个session(用户信息、用户操作记录),并生成一个对应的sessionID返回给客户;
  • 下一次访问网站时候,浏览器发送HTTP请求到服务器,并将上次会话的sessionID发送给服务器(sessionID可以包含在cookie中,如果客户端禁用cookie,seesionID可以附加在URL路径的后面或者作为一个表单字段,传递给服务端);
  • 服务器收到sessionID,会检索出对应的session并识别出用户信息,就可以专门为用户提供响应内容。
2.3.2.3 浏览器禁用Cookie后Session的使用

遇到两种情况:1.用户浏览器禁用了Cookie绝大多数手机浏览器都不支持Cookie

  • Java Web提供了解决方法:URL地址重写

HttpServletResponse类提供了两个URL地址重写的方法:

代码语言:javascript
复制
encodeURL(String url)

encodeRedirectURL(String url)

需要值得注意的是:这两个方法会自动判断该浏览器是否支持Cookie,如果支持Cookie,重写后的URL地址就不会带有jsessionid了【当然了,即使浏览器支持Cookie,第一次输出URL地址的时候还是会出现jsessionid(因为没有任何Cookie可带)

例子

代码语言:javascript
复制
  String url = "/web-01/Servlet5";
  response.sendRedirect(response.encodeURL(url));

URL地址重写的原理: 将Session的id信息重写到URL地址汇总,服务器解析重写后URL获取Session的id,这样一来即使浏览器禁用掉了Cookie,但是Session的id通过服务端传递,还是可以使用Session来记录用户的状态。

2.3.2.4 共享 cookie和session实现单点同域名的登录

基于 cookie-session 机制的系统中,登录系统后会返回一个 sessionId 存储在 cookie 中,如果我们能够让另外一个系统也能获取到这个 cookie,不就获取到凭证信息了,无需再次登录。刚好浏览器的 cookie 可以实现这样的效果(详见web 跨域及 cookie 学习)。

cookie 允许同域名(或者父子域名)的不同端口中共享 cookie,这点和 http 的同域策略不一样(http 请求只要协议、域名、端口不完全相同便认为跨域)。因此只需将多个应用前台页面部署到相同的域名(或者父子域名),然后共享 session 便能够实现单点登录。架构如下:

上面方案显而易见的限制就是不仅前台页面需要共享 cookie,后台也需要共享 session。

这个方案可以用在使用相同的SESSION验证程序的系统中。针对跨域,跨系统(不共享SESSION)则无法使用了。 可参考使用JWT实现单点登录的方案。

3. 参考

(1)JavaScript Cookie https://www.runoob.com/js/js-cookies.html

(2)Cookie的工作原理与使用 http://www.bjpowernode.com/tutorial_session/ 【说明】有交互原理图

(3)Cookie的常用方法及在浏览器中的设置 http://www.bjpowernode.com/tutorial_session/1058.html

(3)Session执行原理、Session的常用方法及Session对象的创建与获取 http://www.bjpowernode.com/tutorial_session/1059.html

(4)浏览器与服务器交互信息的获取 http://www.bjpowernode.com/tutorial_session/1056.html

(5)会话技术——Cookies和Session详解 https://zhuanlan.zhihu.com/p/80832251

(6)cookie原理详解及单点登录原理 https://blog.csdn.net/qq_40299179/article/details/104067789

(7)深入理解Cookie https://www.jianshu.com/p/6fc9cea6daa2 【说明】cookie属性项介绍的比较清楚,包括有效期时间,作用域。

(8)session保存密码_一文读懂会话跟踪技术Cookie、Session的区别 https://blog.csdn.net/weixin_39684495/article/details/109907640

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 摘要
  • 2. 内容
    • 2.1 COOKIE
      • 2.1.1 什么是Cookie?
      • 2.1.2 Cookie的工作原理
      • 2.1.3 cookie属性介绍
      • 2.1.4 cookie规范
      • 2.1.5cookie 常用函数
    • 2.2 SESSION
      • 2.2.1 什么是SESSION?
      • 2.2.2 函数
    • 2.3 COOKIE和SESSION的区别和联系
      • 2.3.1 COOKIE和SESSION的区别
      • 2.3.2 COOKIE和SESSION实现会话跟踪
      • 2.3.2.1 Cookie实现会话跟踪
      • 2.3.2.2 Session实现会话跟踪
  • 3. 参考
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档