理解Cookie Session Token JWT到底是啥子

本篇只是从前端角度去感受这几个东西特别是前端鉴权

说实话 这几个东西说详尽我感觉可以写一本书了

 

HTTP是无状态的,这个怎么理解呢?简单来说 一次HTTP请求(简单说)就是发出和收到回应 好比你网购下单 手快递一样 但是这次买完就完啦,没有啥售后服务什么的,因为HTTP不会对事务进行处理,每次客户端和服务端会话完成之后,服务端不会保存任何的会话信息,每一个请求都是独立的,服务端无法确认是谁访问了他,也没有办法知道是不是同一个人访问了他。

但是在一些场景下就需要HTTP保持和维护一个状态,最广为人知的就是登录,记录用户的登录状态,不然用户每次打开都需要输入用户密码,或者在一个需要登录的网站中,做任何事情都需要重新输入一边用户密码,这太傻逼了。因此就有了cookie 

Cookie

cookie 是由服务器产生发回给客户端,并且保存在客户端的东西。

他的出现是弥补了HTTP没有保存状态的缺点

Cookie 可以作为一个状态保存的状态机,用来保存用户的相关登录状态,当第一次验证通过后,服务器可以通过 set-cookie 令客户端将自己的 cookie 保存起来,当下一次再发送请求的时候,直接带上 cookie 即可,而服务器检测到客户端发送的 cookie 与其保存的 cookie 值保持一致时,则直接信任该连接,不再进行验证操作


这好比你进学校,学校要查你的校园卡一样,看到了校园卡进可以进学校了

cookie就是哪个校园卡。它是以键值对的形式存放在浏览器的一个文本文件

  • 在提供标记的接口,通过 HTTP 返回头的 Set-Cookie 字段,直接「种」到浏览器上
  • 浏览器发起请求时,会自动把 cookie 通过 HTTP 请求头的 Cookie 字段,带给接口

这里详细说明cookie几个重要属性

Domain / Path

这里的两个属性是去限制cookie的空间范围

Domain属性指定浏览器发出 HTTP 请求时,哪些域名要附带这个 Cookie。如果没有指定该属性,浏览器会默认将其设为当前 URL 的一级域名,比如我访问微博https://weibo.com/

之后我访问微博的子域名,比如热搜什么的 就不需要再去验证登录了

果服务器在Set-Cookie字段指定的域名,不属于当前域名,浏览器会拒绝这个 Cookie。

 

Path属性是浏览器发起HTTP请求的时候,哪些路径要附带这个Cookie,只要浏览器发现Path属性是HTTP请求路径的开头部分,就回在头信息中带着这个Cookie

Expires / Max-Age

这两个属性是去限制cookie的时间范围

Expires属性指定一个具体的到期时间,到了指定时间以后,浏览器就不再保留这个 Cookie.

如果不去设置默认为或者设置为了null 则在本次的会话完毕,浏览器窗口关闭之后,这个Cookie就不存在了。

Max-Age属性指定从现在开始 Cookie 存在的秒数,比如60 * 60 * 24 * 365(即一年)。过了这个时间以后,浏览器就不再保留这个 Cookie。

如果同时指定两个属性,Max-Age的优先级更高

一旦这两个属性都没有设置 那么只存在于本次的对话之中,一旦用户关闭了浏览器,浏览器就不再保存这个Cookie

Secure / HttpOnly

这两个属性是去限制cookie的使用方式

Secure属性指定浏览器只有在加密协议 HTTPS 下,才能将这个 Cookie 发送到服务器。另一方面,如果当前协议是 HTTP,浏览器会自动忽略服务器发来的Secure属性

HttpOnly属性指定该 Cookie 无法通过 JavaScript 脚本拿到,主要是Document.cookie属性、XMLHttpRequest对象和 Request API 都拿不到该属性,这样可以防止Cookie被JS读取保护用户隐私

只有当用户发出HTTP请求的时候才会带上Cookie

 

这里写一个示例是HTTP头对于Cookie的读写都是通过Set-cookie这个方式向浏览器写入的

Set-Cookie: username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

 

Session

服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession

Session的实现是依赖于Cookie的。

  1. Session用于存储一次会话的多次请求的数据,存在服务器端。
  2. Session可以存储任意类型,任意大小的数据。

session从字面上讲,就是会话。这个就类似你和一个人交谈,你怎么知道当时和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相等)表明他是张三; session也是类似的道理,服务器要知道当前请求发给自己的是谁。为了做这种区分,服务器就是要给每个客户端分配不同的"身份标识",然后客户端每次向服务器发请求的时候,都带上这个”身份标识“,服务器就知道这个请求来自与谁了。 至于客户端怎么保存这个”身份标识“,可以有很多方式,对于浏览器客户端,大家都采用cookie的方式。

简单来说Session就是服务器端对于Cookie的校验 

 

 

上面是经典的Session校验

  • 浏览器登录发送账号密码,服务端查用户库,校验用户
  • 服务端把用户登录状态存为 Session,生成一个 sessionId
  • 通过登录接口返回,把 sessionId set 到 cookie 上
  • 此后浏览器再请求业务接口,sessionId 随 cookie 带上
  • 服务端查 sessionId 校验 session
  • 成功后正常做业务处理,返回结果

然而Session的扩展性并不是很好在单一的浏览器中还好,在多个服务器中用户请求过来会走一次负载均衡,不一定打到哪台机器上。那一旦用户后续接口请求到的机器和他登录请求的机器不一致,或者登录请求的机器宕机了,session 不就失效了吗?当然面对这个问题有一套解决方案,但是我们如果只是简单的登录

就要求配置session环境那么复杂呢,大可不必

一个登录场景,也不必往 session 存太多东西,那为什么不直接打包到 cookie 中呢?这样服务端不用存了,每次只要核验 cookie 带的「证件」有效性就可以了,也可以携带一些轻量的信息。

这个时候我们就需要使用到token(令牌)了

Token

  • 访问资源接口(API)时所需要的资源凭证
  • 特点:
    • 服务端无状态化、可扩展性好
    • 支持移动端设备
    • 安全
    • 支持跨程序调用

token的登录是这样的

 

 

  • 用户登录,服务端校验账号密码,获得用户信息
  • 把用户信息、token 配置编码成 token,通过 cookie set 到浏览器
  • 此后用户请求业务接口,通过 cookie 携带 token
  • 接口校验 token 有效性,进行正常业务接口处理

基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据。用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库、

token 完全由应用管理,所以它可以避开同源策略

 

refresh token

通常我们用于鉴权的token 我们一般称之为access token,但是在一些应用场景中,我们为了信息安全保护通常我们会把access token的时间设置的非常短从而起到保护的作用但是有效期太短了也不好,让用户从新去验证一边登录也不好因为有的时候应该token的有效期非常的短

这个时候就需要使用到refresh token了

  • access token 用来访问业务接口,由于有效期足够短,盗用风险小,也可以使请求方式更宽松灵活
  • refresh token 用来获取 access token,有效期可以长一些,通过独立服务和严格的请求方式增加安全性;由于不常验证,也可以如前面的 session 一样处理

因此有了refresh token之后就可以登录的验证就与以往不同了

 

Session和token的区别

session 和 token 都是边界很模糊的概念,就像前面说的,refresh token 也可能以 session 的形式组织维护。

狭义上,我们通常认为 session 是「种在 cookie 上、数据存在服务端」的认证方案,token 是「客户端存哪都行、数据存在 token 里」的认证方案。对 session 和 token 的对比本质上是「客户端存 cookie / 存别地儿」、「服务端存数据 / 不存数据」的对比。

Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。

不需要服务端整套的解决方案和分布式处理,降低硬件成本;避免查库带来的验证延迟

Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态

认证也有很大的区别

所谓 Session 认证只是简单的把 User 信息存储到 Session 里,因为 SessionID 的不可预测性,暂且认为是安全的。而 Token ,如果指的是 OAuth Token 或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对 App 。其目的是让某 App 有权利访问某用户的信息。

Session 只提供一种简单的认证,即只要有此 SessionID ,即认为有此 User 的全部权利。是需要严格保密的,这个数据应该只保存在站方,不应该共享给其它网站或者第三方 App。所以简单来说:如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了。


JWT

 

posted @   jeffmmo  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示