一、会话跟踪技术Cookie 和 session(面试题)
1、为什么会出现Cookie ?
HTTP协议作是无状态协议,无状态指每次request请求之前是相互独立的,当前请求并不会记录它的上一次请求信息。 存在这样的问题,既然无状态,那完成一套完整的业务逻辑,需要发送多次请求,那么怎么标识这些请求都是同个浏览器操作呢?
-
解决方案:
-
浏览器发送request请求到服务器,服务器除了返回请求的response之外,还给请求分配一个唯一标识ID和response一并返回给浏览器
-
服务器在本地创建一个map结构,专门以key-value存储这个ID标识和浏览器的关系
-
当浏览器的第一次请求后已经分配一个ID,当第二次访问时会自动带上这个标识ID,服务会获取这个标识ID去map里面找上一次request的信息状态且做对应的更新操作 服务端生成这个全局的唯一标识,传递给客户端用于标记这次请求就是cookie; 服务器创建的那个map结构就是session。
-
cookies由服务端生成,用于标记客户端的唯一标识,在每次网络请求中,都会被传送。
-
session服务端自己维护的一个map数据结构,记录key-Object上下文内容状态
-
核心:它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。 浏览器查看多个站点的cookie
-
cookie的属性
-
Name : 名称
-
Value : 值
-
Domain:表示当前cookie所属于哪个域或子域下面
-
Expires/Max-age:表示了cookie的有效期,是一个时间,过了这个时间,该cookie就失效了
-
Path:表示cookie的所属路径。
-
size: 大小,多数浏览器都是4000多个字节
-
http-only: 表示这个cookie不能被客户端使用js读取到,是不公开的cookie
- (chrome调试器的console中输入document.cookie将得不到标记为HttpOnly的字段)
-
Secure: 标记为 Secure 的Cookie只应通过被HTTPS协议(加密过的)请求发送给服务端,
- 从 Chrome 52 和 Firefox 52 开始,不安全的站点(http:)无法使用Cookie的 Secure 标记
Cookie的缺陷
- cookie会被附加在每个HTTP请求中,增加了流量。
- 在HTTP请求中的cookie是明文传递的,所以安全性成问题,除非用HTTPS
- Cookie的大小有限制,对于复杂的存储需求来说不满足
浏览器允许每个域名所包含的cookie数量?
- 多数浏览器允许最多是50个,部分浏览器是30或者20;
- 满后会有多种剔除策略,比如LRU(最近最少使用来剔除),权重(权重低的先剔除)等
2、为什么会出现Session?
- HTTP协议作是无状态协议,无状态指每次request请求之前是相互独立的,当前请求并不会记录它的上一次请求信息。
- 存在这样的问题,既然无状态,那完成一套完整的业务逻辑,需要发送多次请求,那么怎么标识这些请求都是同个浏览器操作呢?
- cookie和session都是为了弥补http协议的无状态特性,对server端来说无法知道两次http请求是否来自同一个用户,利用cookie和session就可以让server端知道多次http请求是否来自同一用户
-
生成和使用流程(和Cookie知识点一样,两者互相配合)
- 浏览器第一次发送request请求到服务器,服务器除了返回请求的response之外,还给请求分配一个唯一标识sessionId和response一并返回给浏览器
- 服务器在本地创建一个map结构,专门以key-value存储这个sessionId和浏览器的关系
- 当浏览器的第一次请求后已经分配一个sessionId,当第二次访问时会自动带上这个标识sessionId
- 服务器通过查找这个sessionId就知道用户状态了,并更新sessionId的最后访问时间。
- 注意: Session是有时限性的:比如如果30分钟内某个session都没有被更新,服务器就会删除这个它。
总结:
- 服务端生成这个全局的唯一标识,传递给客户端用于标记这次请求就是cookie;
- 服务器创建的那个map结构就是session。
- cookies由服务端生成,用于标记客户端的唯一标识,在每次网络请求中,都会被传送。
- session服务端自己维护的一个map数据结构,记录key-Object上下文内容状态
- 总言之cookie是保存在客户端,session是存在服务器,session依赖于cookie
- cookie里面存储的就是JSESSIONID(sessionId),一个cookie里面有很多属性。
-
使用场景:记录用户的登录状态、权限等
-
session的现状
-
session是存储在服务端的内存中,在javaweb里面叫HttpSession也是一个作用域
-
PageContext(页面)->ServletRequest(请求)->【HttpSession】(会话)->ServletContext(一个应用)
-
是可以存储很多key-value的,作用域比较广,所以也不能存储过多内容,因为内存是有限制的,互联网企业使用比较少,传统IT公司使用比较多
-
-
知识延伸:
- 服务端是单机情况下session是可以很用的使用的,但是分布式(多台机器)情况下就存在不能共享的问题。
- 用户A在当前机器登录,突然某次请求到B机器,由于B服务器不存在这个用户的登录信息,所以就会提示重新登录
- 这个场景下就用到分布式存储方案-比如Redis。