理解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的。
- Session用于存储一次会话的多次请求的数据,存在服务器端。
- 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
- JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。是一种认证授权机制
- 这边建议直接看阮一峰老师的http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html的JWT的课
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)