会话跟踪技术:Cookie、Session和Token

背景:

HTTP无状态的协议,即服务器对客户端没有记忆能力,它的每个请求都是完全独立的,并不会保存通信状态。

无状态的后果: 意味着后续发出的请求需要先处理前面请求的响应,则必须重传前面的请求,这导致需要额外传递一些前面的重复请求,才能获取后续响应,会大大浪费资源;

-------------所以需要 会话跟踪技术 来解决无状态的问题 !实现一次会话的多次请求内数据共享!

1. Cookie (客户端的会话跟踪技术)

Cookie的实现是基于HTTP协议的;
Cookie是客户端保存用户信息的一种机制 ,本质是存储在浏览器的一小段文本数据,不超过4kb;

过程
客户端【第一次发送HTTP请求时】,服务器产生Cookie 并返回给浏览器存储,
【以后浏览器每次发送HTTP请求时】,HTTP的请求报文的 请求头 中都会带着Cookie(请求头的格式为键值对),这样就能通过coockie实现同一次会话中 多次请求之间的数据共享;

缺点: 安全性

  1. Cookie是放在【HTTP请求报文】的头部行中,是以明文形式在网络中传输,若没有加密,一旦被截获,可以直接获取隐私信息
  2. 由于HTTP协议不会验证双方的身份,即使是Cookie被MD5加密,一旦Cookie被截获,把别人的Cookie向服务器提交,并且能够通过验证,就可以冒充受害人的身份登陆网站--------Cookie欺骗

1.1 原理

  • 浏览器访问服务器后,在servletA创建了Cookie对象并封装respond对象中,
  • Tomcat解析respond对象,会将Coockie键值对放到HTTP响应报文的 响应头 set-cookie:username=zs
  • 浏览器拿到并解析响应报文,拿到数据username=zs并存储;
  • 当下一次浏览器要访问servletB,会在HTTP请求报文的 请求头 中带上:cookie:username=zs
  • Tomcat解析浏览器发送的HTTP请求报文,将数据存入 request对象,通过request对象来获取Cookie数组;
    在这里插入图片描述

1.2 基本使用

作为服务端,需要关注的:
①发送Cookie,
②接收到Cookie后获取其中的信息

1.2.1 服务器发送Cookie

  1. 在Servlet中,创建Cookie对象,设置键值对数据;
    在这里插入图片描述

  2. 将Cookie对象添加到Response对象,而后由Tomcat读取respond中数据并拼接成HTTP响应报文格式发给客户端;
    在这里插入图片描述

例:服务器发送Cookie
在这里插入图片描述
启动Tomcat,访问aServlet就会执行cookie相关代码;

查看响应报文(响应头):
在这里插入图片描述

此时打开浏览器设置,能找到刚才发送的Cookie:
在这里插入图片描述

1.2.2 服务器获取Cookie

注:浏览器访问服务器时会在HTTP请求报文的【请求头】中携带着所有Cookie,每对用分号隔开;
在这里插入图片描述

  1. 使用request对象来获取Cookie数组
    在这里插入图片描述
  2. 遍历Cookie数组,获取每一个Cookie
  3. 使用Cookie对象方法获取数据;
    在这里插入图片描述

例:获取Cookie数组,只取出name=”username“的那个Cookie,打印出name和value:
在这里插入图片描述
此时访问bServlet,浏览器携带了Cookie,由servlet获取,在控制台打印:
在这里插入图片描述

1.3 使用细节

1.3.1 存活时间

【默认情况下】,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,Cookie会被销毁;

Cookie持久化setMaxAge(int seconds) 设置Cookie存活时间;

  1. 正数:将Cookie写入浏览器所在磁盘,持久化存储!到时间自动删除
  2. 负数,默认值,Cookie存在浏览器内存中,浏览器关闭,则Cookie被销毁
  3. 零:删除对应Cookie

1.3.2 存储中文

默认情况下不能存储中文!
解决

  1. 将value用URL编码
    在这里插入图片描述
  2. 中文被编码为:
    在这里插入图片描述
  3. 再对value进行解码
    在这里插入图片描述
    成功解码:
    在这里插入图片描述

2. Session(服务端的会话跟踪技术)

引入
1.Cookie是纯文本,且只有几kb 存的内容太少;
2.Cookie中直接放数据,不安全,容易被截取;

Session机制一般借助Cookie来实现
session对象存储在服务器中,用于记录用户的状态
sessionID无规律的字符串,存储在浏览器端的【Cookie中】;
当浏览器【发送HTTP请求时】会带着sessionID,服务器根据SessionID就能找出用户信息
session会配置一个过期时间(默认30min),过期后需要重新登录;

当客户端第一次访问服务器时,【服务器创建session出来后】,会把sessionID以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号,服务器发现客户机浏览器带sessionID过来了,就会使用中与之对应的session为之服务。

运行机制:
1.主机的浏览器进程与服务器进程建立浏览器连接
2.当用户浏览器进程【第一次向服务器进程发送HTTP请求报文时】,Web服务器就会为其产生一个唯一的 sessionID,并以此为索引在Web服务器内存中创建session对象,用来记录该用户访问该网站的各种信息(setAttribute()),一次会话中的不同请求就可以共享这个Session对象的数据了;
3.接着Web服务器给浏览器进程发回HTTP响应报文,在响应报文中,包含一个首部字段为Set-Cookie的首部行,该字段由服务器写入了sessionID,以及会话结束时间
4.当浏览器进程收到该响应报文后,就在一个特定的Cookie文件中添加一行,记录该服务器的域名和Cookie;
5.【当用户再次使用浏览器访问这个网站时】,每发送一个HTTP请求报文,浏览器都会从Cookie文件中取出该网站的sessionID,并放到HTTP请求报文的Cookie 头部行 中,Web服务器根据sessionID就可以识别该用户,返回相关信息;

2.1 原理

Session是基于Cookie实现的;
在这里插入图片描述

为什么在一次会话的多次请求之间获取的都是同一个Session对象 ?
浏览器访问服务端,servlet会自动生成Session对象ID并放入Cookie,发给浏览器(HTTP响应报文的响应头);
在这里插入图片描述

浏览器收到后将SessionID存入内存/磁盘;
下次浏览器携带着Cookie:SessionID=10 访问Servlet,Servlet收到SessionID后寻找这个SessionID的对象,如果有就直接使用,没有则创建新的Session对象;
在这里插入图片描述

而当另一个浏览器的请求3访问Servlet时没有携带sessionID、或者SessionID不一样,servlet就无法获取刚才sessionID=10的SessionID对象,这就保证了同一个会话的session是同一个;

2.2 基本使用

2.2.1 获取Session对象

在这里插入图片描述

2.2.1 Session对象的功能

在这里插入图片描述
注:setAttribute的值可以存任意类型!

例:
ServletDemo1请求1:通过request对象获取Session对象并存数据( setAttribute()
在这里插入图片描述
ServletDemo2请求2:直接获取Session并读取数据,就是请求1存的数据,即访问同一个Session对象!( getAttribute() )
在这里插入图片描述
在这里插入图片描述

输出zs;
即session对象被两次请求所访问,即在一次会话的两次请求之间共享数据!

2.3 使用细节

2.3.1 Session钝化、活化

钝化(序列号):【服务器正常关闭后】,Tomcat会自动将Session对象的数据写入磁盘;
活化(反序列化):再次启动服务器后,从文件加载数据并转化为Session对象;
Session是对象,钝化即序列号,活化即反序列化;

2.3.2 Session销毁

  1. 默认情况下,误操作,Session会在30分钟内销毁(提示:登陆时间太长没有操作,已经自动退出请重新登陆)
    也可以在xml文件中设置时间:
    在这里插入图片描述

  2. 调用Session对象的invalidate()方法,如前端用户选择“登出”时,就需要销毁Session !

注意:
浏览器中途关闭,再次访问时,不是同一个Session对象,因为已经不是同一次会话了!

2.4 Session的共享问题

当使用Session来存储用户数据时,多台Tomcat并不共享session存储进空间 !当切换到不同的Tomcat服务器时导致数据丢失的问题!(每个Tomcat都有自己的session空间);

解决:让session可以在服务器之间共享;

早期
Tomcat使用session互相拷贝; 但是①多台服务器拷贝浪费空间 ②拷贝需要时间,有延迟(服务器是进程,进程通信效率低)

现在:
使用 Redis 充当缓存服务器!让每个服务器都能访问Redis中的用户信息;
在这里插入图片描述

Cookie与Session的区别:

Cookie和Session都是完成一次会话多次请求间的数据共享;

  1. 储存:cookie储存在浏览器内存/磁盘(可以自己设置),
    session对象储存在服务器中(钝化、活化),而sessionID存于Cookie中,
  2. 安全性:session比cookie更加安全
    ①Cookie直接存数据,每次都在网络中传输,容易被盗取、截获;
    ②seesionID是随机字符串而不是明文且不记录数据,数据是在Session对象中在服务器,避免了直接存用户名密码,提高安全性
    有会话时间限制,且可以选择使用签名,而cookie容易造成cookie欺骗
  3. 数据类型不同:cookie只支持字符串数据,session对象可以储存任意类型数据(Object)!
  4. 有效期不同:cookie存活时间可设置较长时间,而session存活时间相对较短(默认30min);
  5. 存储大小不同:单个cookie的数据不能超过4KB,session储存的数据内容可以更大,即在一次会话中多次请求共享的数据也就更多;

3. Token

引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生

token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个令牌,当用户第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码,减轻服务器的压力。

运行机制:

1.客户端使用用户名跟密码请求登录;
2.服务端收到请求,去验证用户名与密码;
3.验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端;
4.客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里;
5.客户端每次向服务端请求资源的时候需要带着服务端签发的 Token;
6.服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据。

服务器并不保存token,而是通过数据签名的方法,对数据用算法(如SHA-256)与私钥进行签名后作为Token,当Token发送给服务器时,服务会通过相同的算法与密钥进行签名,如果和Token中的签名相同,服务器就知道用户已经登录过了,并且可以直接得到用户的userID。(服务器用cpu的计算时间来换取了储存空间

token和session的区别?
token和session其实都是为了身份验证
服务端session存用户数据,客户端访问服务端的时候,根据sessionid找用户数据;而使用token时服务端只有一段加密代码;
同样,session和token都是有过期时间一说,都需要去管理过期时间;
其实token与session的问题是一种时间与空间的博弈问题,session是空间换时间,而token是时间换空间。两者的选择要看具体情况而定。

虽然确实都是“客户端记录,每次访问携带”,但使用token则后端不需要记录什么东西,每次解密验证即可
而 sessionid ,一般都是一段随机字符串,需要到后端去检索 id 的有效性

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值