Session 和 Cookie

原文链接:https://www.yuque.com/tianxinxiansheng-dye0k/ydein8/sw8ek8r4764qs81m

hello,大家面试有被问过 Cookie 和 Session 有什么区别 的问题吗?

当面试官问我的时候,我首先想到的是 sessionStorage 和 Cookie 的区别,当时我就想那还有一个 localStroage 的为啥不一起问,聊着聊着发现不对。

我想,对于一个前端来说,Session 是不需要很了解的,这是服务端的东西,为什么需要考查前端呢?然而等我面试以后查资料才发现我太天真了,在前端开发中,了解 Session 是非常重要的,因为它涉及到用户与Web 应用程序之间的交互和状态管理;客户端会在发送请求的时候,自动将本地存活的 Cookie 封装在信息头发送给服务器。

1. 起源

我们都知道 HTTP 本身是不保存任何用户的状态信息的,所以 HTTP 是无状态的协议,为什么 HTTP 不能有状态呢?

如果需要让 HTTP 自己变成有状态的,就意味着 HTTP 协议需要保存交互的状态信息,先不说这种方式是否合适,单从维护状态信息这一点来说,代价就很高,因为既然保存了状态信息,那后续的一些行为也会受到状态信息的影响。

最初的 HTTP 协议只是用来浏览静态文件的,无状态协议已经足够,这样实现的负担也很轻。但是随着 Web 技术的不断发展,越来越多的场景需要状态信息能够得以保存来做一些事情;那么这个时候就需要来 装饰 一下 HTTP,引入其他机制来实现有状态,

那些机制呢?Cookie 和 Session,通过引入 Cookie 和 Session 体系机制来维护状态信息。即用户第一次访问服务器的时候,服务器响应报头通常会出现一个 Set-Cookie 响应头,这里其实就是在本地设置一个 Cookie,当用户再次访问服务器的时候,http 会附带这个 Cookie 过去,Cookie 中存有 SessionID 这样的信息来到服务器确认是否属于同一次会话。

2. 什么是 Cookie 和 Session ?

Cookie 和 Session 是用来跟踪浏览器用户身份的会话技术,是一种机制,它们可以实现在多个页面之间共享用户的状态。

2.1. 什么是 Cookie

Cookie是浏览器提供的持久化存储数据的,浏览器第一次发送请求到服务器,服务器就创建 Cookie,该 Cookie 中包含着信息,可以是用户的信息包括用户偏好设置、广告偏好等,然后将该 Cookie 发送到浏览器。

浏览器之后再次访问服务器时就会携带服务器创建的 Cookie,这不需要我们做任何操作,不需要写任何代码,浏览器帮我们实现了在每一次的请求中都携带上 Cookie。它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。

Cookie 在存的时候,是按照浏览器 + 域名的维度来进行细分的,不同的浏览器有各自的 Cookie,同一个浏览器不同的域名,对应不同的 Cookie。

Cookie 登陆场景,登陆过一次网站,第二次访问不需要输入账号密码自动登陆,就是把信息写到 Cookie 里,访问网站的时候,网站页面的脚本读取 Cookie,自动帮你把用户名填写了

Cookie 主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

Cookie 的主要内容

Name

设置的 Cookie 的名字,一旦创建,不可更改;但是 Chrome 的 application 面板里面可以修改 Cookie 的 name。

Value

name 对应的 value。

  1. 如果会用 Unicode,需要为字符编码;
  2. 如果为二进制数据,需要使用 BASE-64 编码。

Expires / Max-Age

设置 Cookie 的过期时间,单位秒。

  1. 正数,Cookie 在 maxAge 后消失;
  2. 负数,临时 Cookie,关闭浏览器即失效;
  3. 0,删除该 Cookie;
  4. 默认 -1。

Domain

该 Cookie 在哪个域名中有效。一般设置子域名,比如 lz.cc.com。

Path

该 Cookie 在哪个路径下有效。

  1. 如果设置为 "/sessionWeb" 则只有 路径 为 "/sessionWeb" 的程序可以访问该 Cookie;
  2. 如果设置为 "/",则本域名下 路径 都可以访问该 Cookie。

Secure

设为 true,http 不可以访问。

HttpOnly

设为 true,限制非 HTTP 协议程序接口对客户端 Cookie 进行访问;也就是说如果想要在客户端取到 HttpOnly 的Cookie 的唯一方法就是使用 AJAX,将取 Cookie 的操作放到服务端,接收客户端发送的 ajax 请求后将取值结果通过HTTP 返回客户端。这样能有效的防止 XSS 攻击。

优点

  • 可以长时间保存;
  • 可以在客户端设置。

缺点

  • 安全性相对较差,容易被不法分子获取
  • 存储容量有限,一般只能存储 ASCII 码
  • 失效时间可以设置,但是客户端可以随时清除 Cookie

2.2. 什么是 Session

Session 是 Web 应用程序中的一种 会话 管理机制,用于存储和维护用户的 会话 状态。

当用户访问 Web 应用时,服务器会创建一个唯一的会话 ID,并将其存储在用户的浏览器中的 Cookie 中。在接下来的请求中,浏览器会将会话 ID 作为参数发送给服务器,以便服务器可以识别用户并将其请求与之前的请求相关联。

Session 代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。

每个用户都会产生一个 Session,Session 过多的时候会消耗服务器资源,所以大型网站会有专门的 Session服务器;集群时考虑 Session 的转移,大型网站会有专门的 Session 服务器集群来保存用户会话,这个时候 Session 一般存放在内存中。

销毁场景

  • 服务器(非正常)关闭;
  • Session过期;
  • 手动销毁:session.invalidate()。

优点

  • 安全性相对较高
  • 存储容量大并且可以存储任意数据类型
  • 可以设置失效时间

缺点

  1. Cookie 被禁止,Session 也会被禁止,不过可以通过 url 重写摆脱托 Cookie;
  2. 存储在服务器端,需要占用服务器资源(比如内存资源);
  3. 失效时间短,一般只有数分钟或数小时;
  4. 难以跨域共享,不同域名的服务器无法共享 Session。

服务器关闭,Session 不一定销毁,因为 Session 有时间的,看 Session 是否过期。

3. Cookie 和 Session 有什么不同?

3.1. 存储位置不同

  • Cookie 通过将数据信息存放在 浏览器/客户端 来记录信息确定用户身份。
  • Session 将用户状态信息存储在服务器上,每个用户都有一个独立的 Session。

3.2. 存储容量大小不同

  • 单个 Cookie 保存的数据不能超过 4K。
  • Session 存储容量大小没有限制;但是考虑对服务器的压力,一般不在 Session 中存放太多数据

3.3. 存储有效期不同

  • Cookie 可以长期存储,只要不超过设置的过期时间,可以一直存储,比如我们经常使用的默认登录功能。
  • Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。

3.4. 安全性 / 隐私策略 不同

  • Cookie 存储在客户端,容易遭到不法获取,早期有人将登录名和密码存储在 Cookie 中导致信息被窃取。
  • Session 存储在服务器上,不存在敏感信息泄漏的风险,安全性较高。

3.5. 域支持范围不同

  • Cookie 支持跨域共享。例如,所有 a.com 的 Cookie 在 a.com 下都能用。
  • Session 不支持跨域共享。例如,www.a.com 的 Session 在 api.a.com 下不能用。

3.6. 存储的数据类型不同

  • Cookie 中只能保管 ASCII 字符串,并需要通过编码方式存储为 Unicode 字符或者二进制数据。
  • Session 中能够存储任何类型的数据,包括且不限于 string,integer,list,map 等。

4. 为什么需要 Cookie 和 Session,他们有什么关联?

说起为什么需要 Cookie 和 Session,这就需要从浏览器开始说起,上面我们说浏览器是没有状态的( HTTP 协议无状态),这意味着浏览器并不知道是甲还是乙在和服务端打交道。这个时候就需要有一个机制来告诉服务端,本次操作用户是否登录,是哪个用户在执行的操作,这套机制的实现就需要 Cookie 和 Session 的配合。

我画了一张图大家可以先了解下 Cookie 和 Session 是如何配合的:

用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session ,请求返回时将此 Session 的唯一标识信息 SessionID 放到 Cookie 中发送给浏览器,浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名。

当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。

根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

5. 为什么 Session 需要 Cookie

5.1. Session 的工作原理

  • 当浏览器端第一次发送请求到服务器端时,服务器端会创建一个 Session,并同时生成一个特殊的 Cookie,然后将这个 Cookie 发送至浏览器端。
  • 当浏览器端后续再发送请求到服务器端时,就会携带这个 Cookie 对象。
  • 服务器端根据这个 SessionID 去查询对应的 Session 对象,从而区分不同的用户。

5.2. 为什么 Session 需要借助 Cookie

  • 传递 SessionID:由于 Session 是存储在服务器端的,服务器需要一种方式来识别不同的客户端。通过 Cookie,服务器可以将 SessionID 传递给客户端,并在后续的请求中通过这个 SessionID 来查找对应的Session 对象。
  • 无状态性:HTTP 协议本身是无状态的,即服务器不会记住客户端的状态。通过 Cookie 和 Session 的结合,可以模拟出一种有状态的会话机制。

5.3. 如果禁用 Cookie, Session 则失效的原因

  • 无法传递 SessionID:当浏览器禁用了 Cookie 后,浏览器在请求服务器时将无法携带 SessionID。
  • 服务器无法识别用户:由于服务器无法从请求中获取到 SessionID,因此无法确定请求来自哪个用户,也就无法找到对应的 Session 对象。
  • Session 失效:由于服务器无法识别用户身份,因此 Session 机制失效,用户需要重新登录或进行其他身份验证操作。

综上所述,Session 需要借助 Cookie 来传递 SessionID 以识别不同的用户,从而实现有状态的会话机制

5.4. 如果浏览器中禁止了 Cookie 怎么办

既然服务端是根据 Cookie 中的信息判断用户是否登录,那么如果浏览器中禁止了 Cookie,如何保障整个机制的正常运转?

第一种方案:每次请求中都携带一个 SessionID 的参数,也可以 Post 的方式提交,也可以在请求的地址后面拼接 xxx?SessionID=123456...。

第二种方案:Token 机制

  • Token 机制多用于 App 客户端和服务器交互的模式,也可以用于 Web 端做用户状态管理。
  • Token:令牌,是服务端生成的一串字符串,作为客户端进行请求的一个标识。Token 机制和 Cookie 和 Session 的使用机制比较类似。
  • 当用户第一次登录后,服务器根据提交的用户信息生成一个 Token,响应时将 Token 返回给客户端,以后客户端只需带上这个 Token 前来请求数据即可,无需再次登录验证。

6. 前端为什么需要了解 Session?

在前端开发中,了解 Session 是非常重要的,因为它涉及到用户与 Web 应用程序之间的交互和状态管理。以下是为什么前端需要了解 Session 的几个关键原因:

  1. 会话安全性
  • Session 机制通常与安全性相关,特别是在处理用户身份验证和授权时。了解 Session 的工作原理和如何保护它们免受攻击(如会话劫持、会话固定等)对于确保 Web 应用程序的安全性至关重要。
  1. 会话生命周期
  • Session 具有特定的生命周期,从创建到过期。了解如何设置和管理 Session 的生命周期可以帮助前端开发者优化用户体验(例如,通过延长活动会话的持续时间)和确保安全性(例如,通过定期使会话过期来减少潜在的安全风险)。
  1. 与后端通信
  • 前端通常需要通过 HTTP 请求与后端服务器进行通信。了解 Session 如何在后端被创建、存储和检索可以帮助前端开发者更好地理解这些请求如何与用户的会话状态相关联。
  • 例如,前端可能需要发送包含会话标识符(如会话 Cookie)的请求头,以便后端能够识别并验证用户的会话。
  1. 解决跨域问题
  • 当涉及跨域请求时(即前端代码从一个域发送请求到另一个域的服务器),Session 管理可能会变得更加复杂。了解如何在这种环境中处理 Session(例如,使用 CORS、JSON Web Tokens 等)可以帮助前端开发者克服这些挑战。
  1. 与Web存储技术(如 localStorage 和 cookies)的比较
  • 了解 Session 与其他 Web 存储技术(如 localStorage 和 cookies)之间的区别和联系可以帮助前端开发者选择最适合其应用程序需求的存储机制。这些技术各有优缺点,适用于不同的用例。
  1. 调试和故障排除
  • 了解 Session 的工作原理可以帮助前端开发者在出现问题时更快地定位和解决问题。例如,如果用户的会话状态出现异常或不一致,了解 Session 的创建、存储和检索过程可以帮助开发者更快地找到问题的根源。

总之,了解 Session 对于前端开发者来说是非常重要的,因为它涉及到用户状态管理、安全性、与后端的通信以及与其他Web存储技术的比较等多个方面。

7. 总结

由于本人水平所限,难免有错误以及不足之处, 屏幕前的靓仔们 如有发现,恳请指出!

一键三连,那将在我的心里世界增添一颗明亮而耀眼的星!

最后希望这篇文章对你有所帮助!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值