【HTTP】WebStorage 本地存储 及 验证机制(登录)
一、本地(浏览器端)存储
storage本地存储可视化
打开开发者工具查看storage存储,请看下图。
本地(浏览器端)存储的方式
-
Cache Storage 缓存存储
使用Cache API创建的任何 DOM 缓存。
-
Cookies 小饼干
是服务器发送到用户浏览器并保存在本地的一小块数据(<4kb),它会在浏览器下次向同一服务器再发起请求时被携带到请求头并发送到服务器上Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。
-
Web storage 浏览器存储
使浏览器能以一种比使用Cookie更直观的方式存储键/值对。
分为Local Storage会话存储 和 Session Storage 本地存储
- Session Storage 会话存储: 为每一个给定的源(given origin)维持一个独立的存储区域,本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。
- Local Storage 本地存储:持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。Localstorage 则以文件的方式存储在本地,只能存储字符串类型的数据,存储对象需要 JSON的stringify和parse方法进行处理。 读取内存比读取硬盘速度要快
-
IndexedDB 浏览器数据库
IndexedDB是一种底层API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。该 API使用索引实现对数据的高性能搜索。虽然WebStorage在存储较少量的数据很有用,但对于存储更大量的结构化数据来说力不从心。而 IndexedDB 提供了这种场景的解决方案。
浏览器本地存储
属性 | cookie | LocalStorage | SessionStorage | IndexedDB |
---|---|---|---|---|
持久性 | 根据过期时间。如果没有指定过期时间,则被移除之前一直有效。 | 移除之前一直有效。 | 当前页面关闭之前一直有效。 | 移除之前一直有效。 |
是否可以阻止JS访问 | 是 | 否 | 否 | 否 |
是否在每个请求中自动发送 | 是(根据请求的域名和路径) | 否 | 否 | 否 |
可强制使用HTTPS | 是 | 否 | 否 | 否 |
大小限制 | 4KB | 5MB | 5MB | 桌面应用50MB,移动设备5MB。可以在用户许可下存储更多。 |
数据类型 | 键值对。键值都是字符串。 | 键值对。键值都是字符串。 | 键值对。键值都是字符串。 | 键值对。支持许多数据类型,并支持复杂的查询。 |
作用域 | 独立域名或子域名 | 独立域名。子域名不可以。 | 独立域名,每个浏览器tab页 | 独立域名,子域名不可以 |
二、验证机制,以解决HTTP无状态
http 是无状态协议,没有记忆能力。缺乏验证机制让服务器认识你的浏览器。
1.cookie载体(机制)
cookie既是一种存储方式,也可以用作验证机制。用户信息随请求发给服务器,服务器可以在响应头里面添加一个 Set-Cookie 选项。浏览器收到响应后通常会保存下 Cookie,之后对该服务器每一次请求中都通过 Cookie 请求头部将 Cookie 信息发送给服务器。另外,Cookie的过期时间、域、路径、有效期、适用站点都可以根据需要来指定
cookie的工作流程
cookie各属性
-
name=value键值对
Set-Cookie: name=value
-
Expires 和 Max-Age
Expires的值是一个时间点(cookie失效时刻=Expires),而Maxage的值是一个以秒为单位时间段(cookie失效时刻= 创建时刻+ Max age)。Expires和Max-Age两者的作用都是限制cookie的有效时间。同时存在时,Maxage优先级高于Expires。
Expires为cookie的失效期
Expires失效期大于一天,expires:7(天数)。
Expires失效期小于1天,以15分钟为例,
expires:new Date( new Date().getTime() + 60*1000*15)
Expires未设置的时候cookie变成了session cookie(会话cookie),会话在浏览器关闭时,session cookie将被删除。
safari浏览器有 session restore 功能,保存session cookie,下次使用的时候session cookie会被还原。
Max-Age为cookie的保质期
Maxage有三种可能值:负数、0、正数。Maxage的默认值是 -1(即有效期为 session会话关闭 );
负数:有效期session; 0:删除cookie; 正数:有效期为创建时刻后多少时间清除
-
Domain 和 Path
Domain是域名,Path是路径,两者加起来就构成了 URL,Domain和Path一起来限制 cookie 能被哪些 URL 访问。即请求的URL是Domain或其子域、且URL的路径是Path或子路径,则都可以访问该cookie。path属性生效的前提是domain属性匹配。(例如,如果 path=/docs,那么 "/docs", "/docs/Web/" 或者 "/docs/Web/HTTP" 都满足匹配的条件)
发生跨域xhr请求时,即使请求URL的域名和路径都满足cookie的Domain和Path,默认情况下cookie也不会自动被添加到请求头部中。设置 axios 允许跨域携带 cookie(默认是不带 cookie)
axios.defaults.withCredentials = true;
-
size:cookie大小
-
Secure
Secure选项用来设置cookie只在确保安全的请求中才会发送。当请求是HTTPS或者其他安全协议时,包含Secure选项的 cookie 才能被发送至服务器。
默认情况下,cookie不会带Secure选项(即为空)。所以默认情况下,不管是HTTPS协议还是HTTP协议的请求,cookie 都会被发送至服务端。但要注意一点,Secure选项只是限定了在安全情况下才可以传输给服务端,但并不代表你不能看到这个 cookie。
-
HttpOnly
设置了 HttpOnly 属性的 cookie 不能使用 JavaScript 经由 Document.cookie 属性、XMLHttpRequest 和 Request APIs 进行访问,以防范跨站脚本攻击(XSS)盗取cookie。请注意,使用HttpOnly创建的cookie仍将与JavaScript启动的请求一起发送。
-
SameSite
控制cookie是否与跨源请求一起发送,从而提供一些防范跨站点请求伪造攻击(Csrf)的保护
SameSite属性值
Lax:Cookie不是在跨站点请求(如对加载图像或帧的调用)上发送的,而是在用户从外部站点导航到源站点时发送的。
Strict:浏览器只为同一站点请求(即来自设置cookie的同一站点的请求)发送cookie。如果请求来自与当前URL不同的URL,则不会发送带有SameSite=Strength属性的cookie。
None:浏览器发送带有跨站点请求和相同站点请求的cookie。当SameSite=None时,还必须设置安全属性!
web storage和cookie的区别
-
web storages和cookie的作用不同,web storage是用于本地大容量存储数据(web storage的存储量大到5MB);而cookie是用于客户端和服务端间的信息传递(也可以存储,但只有4KB);
-
Cookie的大小是受限的,并且每次你请求一个新的页面的时候Cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用。
-
web storage有setItem、getItem、removeItem、clear等方法,cookie需要我们自己来封装setCookie、getCookie、removeCookie
-
但是Cookie也是不可以或缺的:Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生.
2.session机制
- 用来储存用户会话。一个session域对象为一个用户浏览器对象服务。session对象存储在服务器,sessionID通常存储在cookie里,服务器端根据浏览器传来的sessionID使用ID正则校验,找出用户数据。
- session本质上不属于浏览器端存储方式。所以不能和上面的浏览器端的存储方式放在一起,你也无法在开发者工具中查看到session
session的工作流程
cookie和session的区别
- 存储位置:一个浏览器端,一个服务器端
- 安全性:cookie明文存储在浏览器端,安全性差,虽然可以加密算法存在。但是session存放于服务器,安全性仍要比cookie要好。
- 网络传输量:每次请求cookie都将带来性能开销,session本身存放于服务器,通过cookie仅传递sessionID即可
- 大小:cookies保存数据不超过4k,大多浏览器限制一个站点最多保存50个cookie。session则无任何限制
3.token机制
浏览器第一次访问服务器,根据传过来的唯一标识userId,服务器算加并加一个密钥生成一个token,然后通过BASE64编码一下之后将这个token发送给客户端;浏览器可以将用cookie或webStorage保存token,下次请求时,带着token,服务器收到请求后,然后会用相同的算法和密钥去验证token(重新计算token的第三部分签名sign,并且比对),如果通过,执行业务操作,不通过,返回不通过信息;
token的工作流程
token的组成
-
最简单的token组成: uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,以哈希算法压缩成一定长的十六进制字符串)
-
JWT(Json web token)是标准化的token,由header(声明算法),payload(数据:如uid,有效期之类),signature(签名)组成。header和payload两部分由BASE64编码,注意是编码不是加密,是可以解码的。经过header里申明的算法运算,得出signature签名编码(加密过程需要服务端的私钥)。此时一个完整的JWT就完成了。
jwt的token如何形成
token和session的区别
- token放在浏览器端,session对象放在服务器端
- 使用session是用空间换时间,面临大量用户的存储压力 + 分布式系统信息共享。而token是用时间换空间(CPU加解密的时间换取存储空间),也避免了cookie的跨域和安全问题。
4.cookie、session、token总结
- cookie通常作为一种数据载体。cookie跟随http的每个请求发送出去。
- session是由服务器产生并保存在服务器,由服务器主导一切。把sessionID放入cookie中响应给浏览器
- token是由服务器产生但是保存在浏览器,由客户端(浏览器)主导一切。token可以放入cookie或webStorage持久化储存。token可以随请求放入cookie、Authorization、body中,持有token可以像令牌一样访问服务器。
- 虽然三者不是同一时期的产物,但是三者并没有高低之分。取决于业务需求。
三、除token外另外两种登录方式
SSO单点登录
单点登录指的是在公司内部搭建一个公共的认证中心,公司下的所有产品的登录都可以在认证中心里完成,一个产品在认证中心登录后,再去访问另一个产品,可以不用再次登录,即可获取登录状态。
SSO机制
- 用户访问网站 a.com 下的 pageA 页面。
- 由于没有登录,则会重定向到认证中心,并带上回调地址www.sso.com?return_uri=a.com/pageA ,以便登录后直接进入对应页面。
- 用户在认证中心输入账号密码,提交登录。
- 认证中心验证账号密码有效,然后重定向 a.com?ticket=123 带上授权码ticket,并将认证中心 sso.com 的登录态写入 Cookie。
- 在 a.com 服务器中,拿着 ticket 向认证中心确认,授权码 ticket 真实有效。
- 验证成功后,服务器将登录信息写入 Cookie(此时客户端有 2 个 Cookie 分别存有 a.com 和 sso.com 的登录态)。
认证中心登录完成之后,继续访问 a.com 下的其他页面:
这个时候,由于 a.com 存在已登录的 Cookie 信息,所以服务器端直接认证成功。
如果认证中心登录完成之后,访问 b.com 下的页面:
这个时候,由于认证中心存在之前登录过的Cookie,所以也不用再次输入账号密码,直接返回第 4 步,下发 ticket 给 b.com 即可。
SSO 单点登录退出
目前我们已经完成了单点登录,在同一套认证中心的管理下,多个产品可以共享登录态。现在我们需要考虑退出了,即:在一个产品中退出了登录,怎么让其他的产品也都退出登录?
原理其实不难,可以回过头来看第 5 步,每一个产品在向认证中心验证 ticket 时,其实可以顺带将自己的退出登录 api 发送到认证中心。
当某个产品 c.com 退出登录时:c.com sso.com
OAuth 第三方登录
在上文中,我们使用单点登录完成了多产品的登录态共享,但都是建立在一套统一的认证中心下,对于一些小型企业,未免太麻烦,有没有一种登录能够做到开箱即用?
其实是有的,很多大厂都会提供自己的第三方登录服务,我们一起来分析一下。
OAuth 机制实现流程
这里以微信开放平台的接入流程为例:
四、登录方式总结
4 种常见的登录方式,总结一下这 4 种方案的使用场景:
- Cookie + Session历史悠久,适合于简单的后端架构,需开发人员自己处理好安全问题。
- Token 方案对后端压力小,适合大型分布式的后端架构,但已分发出去的 token ,如果想收回权限,就不是很方便了。
- SSO 单点登录,适用于中大型企业,想要统一内部所有产品的登录方式。
- OAuth 第三方登录,简单易用,对用户和开发者都友好,但第三方平台很多,需要选择合适自己的第三方登录平台。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现