存储

JavaScript 存储.png

cookie、session、token

cookie、session产生的背景

HTTP 是无状态的协议,服务器与浏览器为了进行会话跟踪,必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态需要通过 cookie 或者 session 去实现。

Cookie 的实现机制

Cookie是由HTTP服务器设置的,保存在浏览器中。服务器通过Set-Cookie响应头字段来指示浏览器保存Cookie, 浏览器通过Cookie请求头字段来告诉服务器之前的状态。 Cookie中包含若干个键值对,每个键值对可以设置过期时间。cookie 是不可跨域的。

cookie的重要属性

属性 说明
name=value 键值对,设置 Cookie 的名称及相对应的值,都必须是字符串类型
如果值为 Unicode 字符,需要为字符编码。
如果值为二进制数据,则需要使用 BASE64 编码。
domain 指定 cookie 所属域名,默认是当前域名
path 指定 cookie 在哪个路径(路由)下生效,默认是 '/'
如果设置为 /abc,则只有 /abc 下的路由可以访问到该 cookie,如:/abc/read
maxAge cookie 失效的时间,单位秒。如果为整数,则该 cookie 在 maxAge 秒后失效。如果为负数,该 cookie 为临时 cookie ,关闭浏览器即失效,浏览器也不会以任何形式保存该 cookie 。如果为 0,表示删除该 cookie 。默认为 -1。
比 expires 好用
expires 过期时间,在设置的某个时间点后该 cookie 就会失效。
一般浏览器的 cookie 都是默认储存的,当关闭浏览器结束这个会话的时候,这个 cookie 也就会被删除
secure 该 cookie 是否仅被使用安全协议传输。安全协议有 HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。
当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才有效。
httpOnly 如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本 读取到该 cookie 的信息,但还是能通过 Application 中手动修改 cookie,所以只是在一定程度上可以防止 XSS 攻击,不是绝对的安全
SameSite 可以让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。
SameSite

SameSite 可以有下面三种值:

  1. Strict仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页 URL 与请求目标 URL 完全一致。
  2. Lax允许部分第三方请求携带 Cookie
  3. None无论是否跨站都会发送 Cookie

之前默认是 None 的,Chrome80 后默认是 Lax。

接下来看下从 None 改成 Lax 到底影响了哪些地方的 Cookies 的发送?直接来一个图表:
samesite.png
有两点要注意的地方:

  1. HTTP 接口不支持 SameSite=none

如果你想加 SameSite=none 属性,那么该 Cookie 就必须同时加上 Secure 属性,表示只有在 HTTPS 协议下该 Cookie 才会被发送。

  1. 需要 UA 检测,部分浏览器不能加 SameSite=none

IOS 12 的 Safari 以及老版本的一些 Chrome 会把 SameSite=none 识别成 SameSite=Strict,所以服务端必须在下发 Set-Cookie 响应头时进行 User-Agent 检测,对这些浏览器不下发 SameSite=none 属性

Cookie 的安全隐患

HTTP客户端软件(包括curl、Node.js)都可以发送任意的HTTP请求,可以设置任何头字段。Cookie是可以被篡改的!且Cookie是明文传输的。

session

存储位置:session 是基于 cookie 实现的,session 存储在服务器端,sessionId 会被存储到客户端的cookie 中。Session 可以存储在HTTP服务器的内存中,也可以存在内存数据库(如redis)中, 对于重量级的应用甚至可以存储在数据库中。
认证流程
认证流程.png

cookie和session的区别

  • 安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。
  • 存取值的类型不同:Cookie 只支持存字符串数据,Session 可以存任意数据类型。
  • 有效期不同: Cookie 可设置为长时间保持,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。
  • 存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。

认证、授权、凭证

认证:验证当前用户的身份。
授权:授权第三方应用使用用户某些资源的权限。
凭证:用来标记访问者身份的证书

token

访问资源接口(API)时所需要的资源凭证。
JSON Web Token(JWT)是跨域身份验证方案。

简单 token 的组成uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)
特点:

  • 服务端无状态化、可扩展性好
  • 支持移动端设备
  • 安全
  • 支持跨程序调用

认证流程
搜狗截图20200313160727.png

token和session的区别

Session 可以记录会话信息,Token 不会存储会话信息。
安全性:Token 安全性比 Session 好

webStorage

背景

前提:用cookie存储永久数据存在以下几个问题:

1.大小:cookie的大小被限制在4KB。
2.带宽:cookie是随HTTP事务一起被发送的,因此会浪费一部分发送cookie时使用的带宽。
3.复杂性:要正确的操纵cookie是很困难的。只能用document.cookie = '...' 来修改

针对这些问题,在HTML5中,重新提供了一种在客户端本地保存数据的功能,它就是Web Storage。这是HTML5中新增的一个功能,使用它可以在客户端本地建立一个数据库,减轻了服务器端的负担,加快了访问数据的速度。
WebStorage提供了两种API:localStorage(本地存储)和sessionStorage(会话存储)。

localStorage 与 sessionStorage 的不同:

作用范围:

localStorage:只要在同一源下(协议+主机名+端口)就能读取/修改到同一份localStorage数据。
sessionStorage:比localStorage更严苛,除了协议、主机名、端口外,还要求在同一窗口(也就是浏览器的标签页)下。

生存周期:

localStorage:存在本地,永久保存。
sessionStorage:只要关闭浏览器(也包括浏览器的标签页),就会被清空。

应用场景:

localStorage:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据。
sessionStorage:敏感账号一次性登录;

相同:

以下都以localStorage举例。
数据结构:

为标准的键值对(Key-Value)数据类型,简单易扩展,只能存储字符串类型。
对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理。

  • JSON.stringify()将其json对象转为字符串。
  • JSON.parse()将字符串转为json对象格式。

对于图片可以转换成DataUrl(base64)。

存储大小:

一般都是:5MB

存储位置:

都保存在客户端,不与服务器进行交互通信。

使用方法:

写入:

//写入a字段
localStorage["a"]='1';
//写入b字段
localStorage.b='2';
//写入c字段
localStorage.setItem("c",'3'); //推荐

获取:getItem (key)

localStorage.getItem(key)

删除:
将localStorage的所有内容清除:

localStorage.clear()

将localStorage中的某个键值对删除:

localStorage.removeItem(key);

localStorage的键获取:
key()方法,向其中出入索引即可获取对应的键

localStorage.setItem("a","red");
localStorage.setItem("b","black");
for (let i =0;i<localStorage.length;i++){
    console.log(localStorage.key(i));
}
问题:

在iPhone/iPad上有时设置setItem()时会出现诡异的QUOTA_EXCEEDED_ERR错误,这时一般在setItem之前,先removeItem()就ok了。

WebStorage的优点:

(1)存储空间更大:cookie为4KB,而WebStorage是5MB;
(2)节省网络流量:WebStorage不会传送到服务器,存储在本地的数据可以直接获取,也不会像cookie一样每次请求都会传送到服务器,所以减少了客户端和服务器端的交互,节省了网络流量;
(3)对于那种只需要在用户浏览一组页面期间保存而关闭浏览器后就可以丢弃的数据,sessionStorage会非常方便;
(4)快速显示:有的数据存储在WebStorage上,再加上浏览器本身的缓存。获取数据时可以从本地获取会比从服务器端获取快得多,所以速度更快;
(5)安全性:WebStorage不会随着HTTP header发送到服务器端,所以安全性相对于cookie来说比较高一些,不会担心截获,但是仍然存在伪造问题;
参考文章:菜鸟教程—localstorage 必知必会
参考文章:cookies、sessionStorage和localStorage解释及区别
参考文章:傻傻分不清之 Cookie、Session、Token、JWT
参考文章:Cookie/Session 的机制与安全
参考文章:浏览器系列之 Cookie 和 SameSite 属性

阅读 322

推荐阅读