HTTP是无状态的协议,即服务器对客户端没有记忆能力,它的每个请求都是完全独立的,发送请求不涉及到状态变更。
无状态的后果: 意味着后续发出的请求需要先处理前面请求的响应,则必须重传前面的请求,这导致需要额外传递一些前面的重复请求,才能获取后续响应,会大大浪费资源;
-------------所以需要 会话跟踪技术 来解决无状态的问题 !实现一次会话的多次请求内数据共享!
Cookie的实现是基于HTTP协议的;
Cookie是客户端保存用户信息的一种机制 ,本质是存储在浏览器的一小段文本数据,不超过4kb;
过程:
【第一次发送HTTP请求时】,服务器产生Cookie并返回给浏览器存储,
【以后浏览器每次发送HTTP请求时】,HTTP的请求报文的请求头中都会带着Cookie(请求头的格式为字段名和value值)
缺点: 安全性
set-cookie
:username=zscookie
:username=zs作为服务端,需要关注的:
①发送Cookie,
②接收到Cookie后获取其中的信息
在Servlet中,创建Cookie对象,设置数据;
将Cookie对象添加到Response对象,而后由Tomcat读取respond中数据并拼接成HTTP响应报文格式发给客户端;
例:发送Cookie
启动Tomcat,访问aServlet就会执行cookie相关代码;
注:浏览器访问服务器时会在HTTP请求报文的请求头中带着所有Cookie,每对用分号隔开;
例:获取Cookie数组,只取出name=”username“的那个Cookie,打印出name和value:
此时访问bServlet,浏览器携带了Cookie,由servlet获取,在控制台打印:
【默认情况下】,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,Cookie会被销毁;
Cookie持久化: setMaxAge(int seconds)
设置Cookie存活时间;
默认情况下不能存储中文!
解决:
Session机制一般借助Cookie来实现;
session对象存储在服务器中,用于记录用户的状态,
sessionID是无规律的字符串,存储在浏览器端的【Cookie中】;
当浏览器【发送HTTP请求时】会带着sessionID,服务器根据SessionID就能找出用户信息;
session会配置一个过期时间(默认30min),过期后需要重新登录;
当客户端第一次访问服务器时,【服务器创建session出来后】,会把sessionID以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号,服务器发现客户机浏览器带sessionID过来了,就会使用中与之对应的session为之服务。
运行机制:
1.主机的浏览器进程与服务器进程建立浏览器连接
2.当用户浏览器进程【第一次向服务器进程发送HTTP请求报文时】,服务器进程就会为其产生一个唯一的sessionID,并以此为索引在服务器的后端数据库创建session对象,用来记录该用户访问该网站的各种信息
3.接着服务器给浏览器进程发回HTTP响应报文,在响应报文中,包含一个首部字段为Set-Cookie的首部行,该字段由服务器写入了sessionID,以及会话结束时间
4.当浏览器进程收到该响应报文后,就在一个特定的Cookie文件中添加一行,记录该服务器的域名和Cookie;
5.【当用户再次使用浏览器访问这个网站时】,每发送一个HTTP请求报文,浏览器都会从Cookie文件中取出该网站的sessionID,并放到HTTP请求报文的Cookie 头部行 中,服务器根据sessionID就可以识别该用户,返回相关信息;
为什么在一次会话的多次请求之间获取的都是同一个Session对象 ?
浏览器访问服务端,servlet会自动生成Session对象的ID并放入Cookie,发给浏览器(HTTP响应报文的响应头);
浏览器收到后将SessionID存入内存/磁盘;
下次浏览器携带着Cookie:SessionID=10 访问Servlet,Servlet收到SessionID后寻找这个SessionID的对象,如果有就直接使用,没有则创建新的Session对象;
而当另一个浏览器的请求3访问Servlet时没有携带sessionID或者不一样,servlet就无法获取刚才sessionID=10的SessionID对象,这就保证了同一个会话的session是同一个;
例:
ServletDemo1:通过request对象获取Session对象并存数据
ServletDemo2:读取Session并获取数据
输出zs;
即session对象被两次请求所访问,即在一次会话的两次请求之间共享数据!
钝化(序列号):【服务器正常关闭后】,Tomcat会自动将Session数据写入硬盘的文件中;
活化(反序列化):再次启动服务器后,从文件加载数据;
Session是对象,钝化即序列号,活化即反序列化;
默认情况下,误操作,Session会在30
分钟内销毁(提示:登陆时间太长没有操作,已经自动退出请重新登陆)
也可以在xml文件中设置时间:
调用Session对象的invalidate()
方法,如前端用户选择“登出”时,就需要销毁Session !
注意:
浏览器中途关闭,再次访问时,不是同一个Session对象,因为已经不是同一次会话了!
Cookie和Session都是完成一次会话多次请求间的数据共享;
引入: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 的有效性