JavaScript-存储与认证

2020/7/11 JavaScript
// localStorage
1. localStorage数据会永久存储,除非代码或手动删除
2. 大小5M,指的是字符的长度或 utf-16 的编码单元,注意字符的个数并不等于字符的长度
3. localStorage.getItem('key') // 查询
4. localStorage.setItem('key', 'val') // 设置
5. localStorage.removeItem('key') // 删除单个
6. localStorage.clear() // 删除全部
7. 在web开发时可以使用 'web-storage-cache' 这个库来简化操作
8. localStorage会跨标签页存储
9. 与 vuex 和 redux 的区别
   1. vuex 和 redux 存储在内存,localstorage 则以文件的方式存储在本地
   2. vuex 和 redux 用于组件之间的传值,localstorage 则主要用于不同页面之间的传值
   3. 当刷新页面时 vuex 和 redux 存储的值会丢失,localstorage 不会
   4. localStorage 能否代替 vuex 或 redux
      1. 对于不变的数据确实可以,但是当两个组件共用一个数据源(对象或数组)时
         如果其中一个组件改变了该数据源,希望另一个组件响应该变化时,localstorage无法做到,原因就是区别1
10. web-storage-cache // localStorage 封装库
11. localStorage 存储的键值用的 UTF-16 字符编码
12. localStorage 的键是占空间的,也就是说 key 的大小也是有影响的
----------------------------------------------------------------------------------------------
// sessionStorage
1. sessionStorage数据只会存在于当前会话,浏览器关闭则清除
2. 大小5M,指的是字符的长度或 utf-16 的编码单元,注意字符的个数并不等于字符的长度
3. sessionStorage.getItem('key') // 查询
4. sessionStorage.setItem('key', 'val') // 设置
5. sessionStorage.removeItem('key') // 删除单个
6. sessionStorage.clear() // 删除全部
7. 刷新当前页面,或者通过location.href、window.open、或者通过带target="_blank"的a标签打开新标签
   之前的sessionStorage还在,但是如果你是主动打开一个新窗口或者新标签,sessionStorage则不存在
8. 通过location.href、window.open、或者通过带target="_blank"的a标签方式打开新窗口时,会把旧窗口(或标签)
   的sessionStorage数据带过去,但从此之后,新窗口(或标签)的sessionStorage的增删改和旧窗口已经没有关系了
   如果只是在当前标签内跳转新页面(或者刷新),数据还会保留(前提当然是同域)
9. sessionStorage不会跨标签页存储
10. 在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文
11. 打开多个相同的 URL 的 tab 页面,会创建各自的 sessionStorage
12. chrome89 版本后,通过 a 标签 target="_blank" 跳转到新页面时,sessionStorage 就会丢失
    a 标签添加属性 rel="opener" 能够复制,仅仅能复制,之后的更改并不会同步
----------------------------------------------------------------------------------------------
// StorageEvent
1. localStorage 能触发
2. sessionStorage 如果是通过 a 标签打开的不会触发,如果是 iframe 嵌套的会触发
3. 通过事件中的 ev.storageArea 判断是 localStorage 还是 sessionStorage 触发
----------------------------------------------------------------------------------------------
// 存储时加密
1. encodeURIComponent + decodeURIComponent
2. window.btoa + window.atob // base64
3. crypto.subtle // 复杂加密,web API
----------------------------------------------------------------------------------------------
// indexedDB
1. indexedDB 是一个事务性数据库系统
2. 一个基于 js 的面向对象数据库
3. 支持索引
4. 可以存储结构化克隆算法支持的任何对象
5. 不能被结构化克隆算法复制的数据(即不能存储的数据)
  1. Error 以及 Function 对象
  2. DOM 节点
  3. 属性描述符,setters、getters
  4. 原型链上的属性
6. 特点
  1. 以键值对方式存储,键可以是二进制对象
  2. 支持事务
  3. 异步操作,基于回调函数的异步,不是 Promise
  4. 遵循同源策略
  5. 存储空间很大
  6. 支持直接存储二进制内容
7. 对象模型
  1. IDBFactory // 打开/创建或者连接/删除数据库
  2. IDBOpenDBRequest // 打开数据库的请求
  3. IDBDatabase // 数据库连接
  4. IDBObjectStore // 数据库中的一个对象库
  5. IDBTransaction // 事务
  6. IDBRequest // 读写操作等异步操作请求
  7. IDBCursor // 游标,用于遍历或迭代数据库中的多条记录
  8. IDBCursorWithValue // 有 value 属性的游标
  9. IDBIndex // 索引
  10. IDBKeyRange // 主键,获取或索引一组记录
8. 基本操作流程
  1. 打开数据库
  2. 在数据库中创建/打开一个对象仓库
  3. 启动一个事务,并发送一个请求来执行一些数据库操作,像增加或提取数据等
  4. 通过监听事件以等待操作完成
  5. 继续后续的操作
9. 使用场景
  1. 缓存数据,比如游戏数据
  2. 缓存图片、脚本、json 文件等静态资源
  3. service worker 的第三方库,就有利用到 indexedDB
10. indexedDB 封装库
  1. localForage
    1. localForage 通过简单类似 localStorage API 的异步存储来改进你的 Web 应用程序的离线体验,它能存储多种类型的数据,不仅仅是字符串
    2. 有降级策略,如不支持 indexedDB 或 WebSQL,则使用 localStorage
    3. 提供回调 API 和 Promise API
  2. dexie.js
    1. 解决了原生 indexedDB API 的三个主要问题
      1. 不明确的错误处理
      2. 糟糕的查询
      3. 代码复杂性
  3. ZangoDB
    1. 一个类似 MongoDB 的 indexedDB 接口实现,提供了诸如过滤、投影、排序、更新和聚合等大多数 MongoDB 常见的特性
  4. JsStore
    1. 一个具备类似 SQL 语法的简单和先进的 indexedDB 封装实现
----------------------------------------------------------------------------------------------
// 什么是认证 | Authentication
1. 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡
   当你的指纹和系统里录入的指纹相匹配时,就打卡成功)
2. 互联网中的认证:
      用户名密码登录
      邮箱发送登录链接
      手机号接收验证码
      只要你能收到邮箱/验证码,就默认你是账号的主人
----------------------------------------------------------------------------------------------
// 什么是授权 | Authorization
1. 用户授予第三方应用访问该用户某些资源的权限
2. 你在安装手机应用的时候,APP 会询问是否允许授予权限(访问相册、地理位置等权限)
3. 你在访问微信小程序时,当登录时,小程序会询问是否允许授予权限(获取昵称、头像、地区、性别等个人信息)
4. 实现授权的方式有: cookie、session、token、OAuth
----------------------------------------------------------------------------------------------
// 什么是凭证 | Credentials
1. 实现认证和授权的前提是需要一种媒介(证书) 来标记访问者的身份
2. 在战国时期,商鞅变法,发明了照身帖。照身帖由官府发放,是一块打磨光滑细密的竹板,上面刻有持有人的头像和籍贯信息
   国人必须持有,如若没有就被认为是黑户,或者间谍之类的
3. 在现实生活中,每个人都会有一张专属的居民身份证,是用于证明持有人身份的一种法定证件。通过身份证
   我们可以办理手机卡/银行卡/个人贷款/交通出行等等,这就是认证的凭证。
4. 在互联网应用中,一般网站(如掘金)会有两种模式,游客模式和登录模式。游客模式下,可以正常浏览网站上面的文章
   一旦想要点赞/收藏/分享文章,就需要登录或者注册账号。当用户登录成功后,服务器会给该用户使用的浏览器颁发一个令牌(token)
   这个令牌用来表明你的身份,每次浏览器发送请求时会带上这个令牌,就可以使用游客模式下无法使用的功能
----------------------------------------------------------------------------------------------
// 什么是 cookit
// HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息)
// 每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人
// 所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态
// 这个状态用于告知服务端前后两个请求是否来自同一浏览器,而这个状态需要通过 cookie 或者 session 去实现
// cookie 存储在客户端: cookie 是服务器发送到用户浏览器并保存在本地的一小块数据
// 它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上
1. cookit会随每次请求都会加载请求头中发生
2. 大小4KB,本身是用于sever通信的
3. 如果不设置有效时间关闭浏览器就会消失
4. document.cookit //查询
5. document.cookit = 'name=cj' // 设置
6. var today = new Date()
   today.setDate(today.getDate() + 3)
   document.cookit = 'name=cj;expires=' + today // 设置过期时间
7. 修改cookit直接重新赋值,注意要保障 path 和 domain 不变
8. 删除cookit可以把有效期设置成少于当前时间即可 // expires设置的过期时间是UTC格式
9. expires设置的过期时间是UTC格式, 可用 Date.prototype.toUTCString() 转换
10. domain表示的是cookie所在的域 // document.cookit = 'name=cj;domain=.abc.com'
      设置
         顶级域名只能设置domain为顶级域名,不能设置为二级域名或者三级域名,否则cookie无法生成
         如www.abc.com能设置domain为abc.com或者www.abc.com,但不能设置domain为news.abc.com,这样cookie不会生成
      读取
         顶级域名只能获取到domain设置为顶级域名的cookie,其他domain设置为二级域名的无法获取
      删除
         顶级域名的cookie在顶级域名或者二级域名都可以删除,但是用非顶级域名访问的网站要删除顶级域名的cookie
         需要设置获取到的cookie的domain为顶级域名,这样才能删除顶级域名的cookie,否则无法删除
         默认的会删除访问的域名下对应的cookie,而不是顶级域名的
         删除二级域名自身生成的cookie不需要设置domain,可以直接删除
11. path表示cookie所在的目录 // document.cookit = 'name=cj;path=/'
      cookie1的path为/tag/
      cookie2的path为/tag/id/
      那么tag下的所有页面都可以访问到cookie1,/tag//tag/haorooms/的子页面不能访问cookie2
      这是因为cookie2能让其path路径下的页面访问
12. maxAgecookie 失效的时间,单位秒。如果为整数,则该 cookie 在 maxAge 秒后失效
    如果为负数,该 cookie 为临时 cookie ,关闭浏览器即失效,浏览器也不会以任何形式保存该 cookie
    如果为 0,表示删除该 cookie 。默认为 -1, 比 expires 好用
13. cookie 是不可跨域的, 一级域名和二级域名之间是允许共享使用的(靠的是 domain)
14. secure表示 cookie 是否仅被使用安全协议传输,安全协议有 HTTPS,SSL,在网络上传输数据之前先将数据加密
    默认为false,当 secure 值为 true,cookie 在 HTTP 中是无效,HTTPS 中才有效
15. httpOnly表示如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本 读取到该 cookie 的信息
    但还是能通过 Application 中手动修改 cookie,所以只是在一定程度上可以防止 XSS 攻击,不是绝对的安全
16. SameSite 表示允许服务器设置一定 cookie 不随跨域请求发送,使用时 secure 必须是 true
  1. None:浏览器不限制,同站和跨站都可以发送 cookie
    1. 同源:协议+端口+域名一致
    2. 同站:有效顶级域名+二级域名,不包含端口和协议
      1. 同站例子:a.taobao.com 和 b.taobao.com
      2. 同站例子:127.0.0.1:8000127.0.0.1:443
      3. 跨站例子:a.github.io 和 b.github.io // github.io 是一个顶级域名
  2. Strict:浏览器只在相同站点发送 cookie
  3. Lax:新版浏览器默认选项,允许部分第三方请求携带 cookie,以下 3 种,跨站时也可以携带
    1. <a href="" /> // a 标签
    2. <link href="" rel="prerender"> // 预加载
    3. <form method="GET" action="" /> // get 表单
17. cookie 不跨域共享或传递
   1. 前后端要开启 withCredentials 配置,前端是 ajax,后端是 cors 头
   2. 现代浏览器开始禁止第三方 js 设置 cookie,为了打击第三方广告,保护用户隐私
      在 set-cookie 时有对应的属性 SameSite: Strict/Lax/None
18. 注意点:
      因为存储在客户端,容易被客户端篡改,使用前需要验证合法性
      不要存储敏感数据,比如用户密码,账户余额
      使用 httpOnly 在一定程度上提高安全性
      尽量减少 cookie 的体积,能存储的数据量不能超过 4kb
      设置正确的 domain 和 path,减少数据传输
      cookie 无法跨域
      一个浏览器针对一个网站最多存 20 个Cookie,浏览器一般只允许存放 300 个Cookie
      移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token
19. 会话期 cookie:浏览器会话期间的 coookie,浏览器关闭以后自动删除,实现方式是不指定过期时间(expires)和有效期(maxAge)
20. 持久化 cookie:存储在客户端的硬盘中,取决于过期时间和有效期
21. 新版的 cookie API,CookieStore,兼容性不太好
22. 后端通过 set-cookie 方法设置 cookie 后需要加了 path 属性,否则在浏览器中的 application 的 cookie 中看不到对应的值
    如果不设置 path 属性和不设置时间则需要关闭浏览器才可以重置
23. 不同浏览器下的相同的域名使用的 cookie 值不一样,因为每个浏览器的 cookie 的存储方式不一样
----------------------------------------------------------------------------------------------
// 什么是 Session
1. session 是另一种记录服务器和客户端会话状态的机制
2. session 是基于 cookie 实现的,session 存储在服务器端,sessionId 会被存储到客户端的cookie 中
3. session 认证流程:
      用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session
      请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器
      浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名
      当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端
      服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效
      如果找到 Session 证明用户已经登录可执行后面操作
4. 根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态
5. 注意点:
      将 session 存储在服务器里面,当用户同时在线量比较多时,这些 session 会占据较多的内存,需要在服务端定期的去清理过期的 session
      当网站采用集群部署的时候,会遇到多台 web 服务器之间如何做 session 共享的问题,因为 session 是由单个服务器创建的
      但是处理用户请求的服务器不一定是那个创建 session 的服务器,那么该服务器就无法拿到之前已经放入到 session 中的登录凭证之类的信息了
      当多个应用要共享 session 时,除了以上问题,还会遇到跨域问题,因为不同的应用可能部署的主机不一样,需要在各个应用做好 cookie 跨域的处理
      sessionId 是存储在 cookie 中的,假如浏览器禁止 cookie 或不支持 cookie 怎么办?
      一般会把 sessionId 跟在 url 参数后面即重写 url所以 session 不一定非得需要靠 cookie 实现
      移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token
----------------------------------------------------------------------------------------------
// Cookie 和 Session 的区别
1. 安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的
2. 存取值的类型不同: Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型
3. 有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短
   客户端关闭(默认情况下)或者 Session 超时都会失效
4. 存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源
----------------------------------------------------------------------------------------------
// 什么是 Token(令牌)
1. Acesss Token
   访问资源接口(API)时所需要的资源凭证
   简单 token 的组成: uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token 的前几位以哈希算法压缩成的一定长度的十六进制字符串)
   服务端无状态化、可扩展性好、支持移动端设备、安全、支持跨程序调用
   token 的身份验证流程:
      客户端使用用户名跟密码请求登录
      服务端收到请求,去验证用户名与密码
      验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端
      客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里
      客户端每次向服务端请求资源的时候需要带着服务端签发的 token
      服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据
      每一次请求都需要携带 token,需要把 token 放到 HTTP 的 Header 里
      基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据
      用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库
      token 完全由应用管理,所以它可以避开同源策略
2. Refresh Token
   refresh token 是专用于刷新 access token 的 token,如果没有 refresh token,也可以刷新 access token
   但每次刷新都要用户输入登录用户名与密码,会很麻烦,有了 refresh token,可以减少这个麻烦
   客户端直接用 refresh token 去更新 access token,无需用户进行额外的操作
   Access Token 的有效期比较短,当 Acesss Token 由于过期而失效时,使用 Refresh Token 就可以获取到新的 Token
   如果 Refresh Token 也失效了,用户就只能重新登录了
   Refresh Token 及过期时间是存储在服务器的数据库中,只有在申请新的 Acesss Token 时才会验证
   不会对业务接口响应时间造成影响,也不需要向 Session 一样一直保持在内存中以应对大量的请求
3. 注意点:
      如果你认为用数据库来存储 token 会导致查询时间太长,可以选择放在内存当中。比如 redis 很适合你对 token 查询的需求
      token 完全由应用管理,所以它可以避开同源策略
      token 可以避免 CSRF 攻击(因为不需要 cookie 了)
      移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token
----------------------------------------------------------------------------------------------
// Token 和 Session 的区别
1. Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息
   而 Token 是令牌,访问资源接口(API)时所需要的资源凭证,Token 使服务端无状态化,不会存储会话信息
2. Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击
   而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态
3. 所谓 Session 认证只是简单的把 User 信息存储到 Session 里,因为 SessionID 的不可预测性,暂且认为是安全的
   而 Token ,如果指的是 OAuth Token 或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对 App
   其目的是让某 App 有权利访问某用户的信息,这里的 Token 是唯一的,不可以转移到其它 App上,也不可以转到其它用户上
   Session 只提供一种简单的认证,即只要有此 SessionID ,即认为有此 User 的全部权利,是需要严格保密的
   这个数据应该只保存在站方,不应该共享给其它网站或者第三方 App,所以简单来说: 如果你的用户数据可能需要和第三方共享
   或者允许第三方调用 API 接口,用 Token,如果永远只是自己的网站,自己的 App,用什么就无所谓了
----------------------------------------------------------------------------------------------
// 什么是 JWT
1. JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案
2. 是一种认证授权机制
3. JWT 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准(RFC 7519,JWT 的声明一般被用来
   在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,比如用在用户登录上
4. 可以使用 HMAC 算法或者是 RSA 的公/私秘钥对 JWT 进行签名,因为数字签名的存在,这些传递的信息是可信的
5. JWT 认证流程:
      用户输入用户名/密码登录,服务端认证成功后,会返回给客户端一个 JWT
      客户端将 token 保存到本地(通常使用 localstorage,也可以使用 cookie)
      当用户希望访问一个受保护的路由或者资源的时候,需要请求头的 Authorization 字段中使用Bearer 模式添加 JWT
         : Authorization: Bearer复制代码
      服务端的保护路由将会检查请求头 Authorization 中的 JWT 信息,如果合法,则允许用户的行为
      因为 JWT 是自包含的(内部包含了一些会话信息),因此减少了需要查询数据库的需要
      因为 JWT 并不使用 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域资源共享问题(CORS)
      因为用户的状态不再存储在服务端的内存中,所以这是一种无状态的认证机制
6. 使用方式
      客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage
      当用户希望访问一个受保护的路由或者资源的时候,可以把它放在 Cookie 里面自动发送,但是这样不能跨域
      所以更好的做法是放在 HTTP 请求头信息的 Authorization 字段里,使用 Bearer 模式添加 JWT
      用户的状态不会存储在服务端的内存中,这是一种 无状态的认证机制
      服务端的保护路由将会检查请求头 Authorization 中的 JWT 信息,如果合法,则允许用户的行为
      由于 JWT 是自包含的,因此减少了需要查询数据库的需要
      JWT 的这些特性使得我们可以完全依赖其无状态的特性提供数据 API 服务,甚至是创建一个下载流服务
      因为 JWT 并不使用 Cookie ,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域资源共享问题(CORS)
      跨域的时候,可以把 JWT 放在 POST 请求的数据体里
      通过 URL 传输
7. 注意点:
      因为 JWT 并不依赖 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域资源共享问题(CORSJWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次
      JWT 不加密的情况下,不能将秘密数据写入 JWT
      JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数
      JWT 最大的优势是服务器不再需要存储 Session,使得服务器认证鉴权业务可以方便扩展。但这也是 JWT 最大的缺点
      由于服务器不需要存储 Session 状态,因此使用过程中无法废弃某个 Token 或者更改 Token 的权限
      也就是说一旦 JWT 签发了,到期之前就会始终有效,除非服务器部署额外的逻辑
      JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用
      JWT的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证
      JWT 适合一次性的命令认证,颁发一个有效期极短的 JWT,即使暴露了危险也很小
      由于每次操作都会生成新的 JWT,因此也没必要保存 JWT,真正实现无状态
      为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输
----------------------------------------------------------------------------------------------
// Token 和 JWT 的区别
1. 相同:
      都是访问资源的令牌
      都可以记录用户的信息
      都是使服务端无状态化
      都是只有验证成功后,客户端才能访问服务端上受保护的资源
2. 区别:
      Token:服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效
      JWT:将 Token 和 Payload 加密后存储于客户端,服务端只需要使用密钥解密进行校验(校验也是 JWT 自己实现的)即可
      不需要查询或者减少查询数据库,因为 JWT 自包含了用户信息和加密的数据
----------------------------------------------------------------------------------------------
// 常见的前后端鉴权方式
1. Session-Cookie
2. Token 验证(包括 JWT,SSO3. OAuth2.0(开放授权),如使用微信扫码登录,QQ 登录等第三方
----------------------------------------------------------------------------------------------
// 如何实现 SSO 单点登录,即在百度登录了,访问百度图片时就默认登录了
1. 主域名相同,则可共享 cookie
2. 主域名不同,则需使用 SSO,即登录模块使用第三方,多个系统的登录都需要集成第三方,本身不需要做登录逻辑
----------------------------------------------------------------------------------------------
// 常见的加密算法
1. 哈希算法(Hash Algorithm)又称散列算法、散列函数、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法
   哈希算法将数据重新打乱混合,重新创建一个哈希值
2. 哈希算法主要用来保障数据真实性(即完整性),即发信人将原始消息和哈希值一起发送,收信人通过相同的哈希函数来校验原始数据是否真实
3. 哈希算法通常有以下几个特点:
      正像快速:原始数据可以快速计算出哈希值
      逆向困难:通过哈希值基本不可能推导出原始数据
      输入敏感:原始数据只要有一点变动,得到的哈希值差别很大
      冲突避免:很难找到不同的原始数据得到相同的哈希值,宇宙中原子数大约在 1060 次方到 80 次方之间
      所以 2256 次方有足够的空间容纳所有的可能,算法好的情况下冲突碰撞的概率很低
      2128 次方为 340282366920938463463374607431768211456,也就是 1039 次方级别
      2160 次方为 1.4615016373309029182036848327163e+48,也就是 1048 次方级别
      2256 次方为 1.1579208923731619542357098500869 × 1077 次方,也就是 1077 次方
4. 以上不能保证数据被恶意篡改,原始数据和哈希值都可能被恶意篡改,要保证不被篡改,可以使用RSA 公钥私钥方案,再配合哈希值
5. 哈希算法主要用来防止计算机传输过程中的错误,早期计算机通过前 7 位数据第 8 位奇偶校验码来保障(12.5% 的浪费效率低)
   对于一段数据或文件,通过哈希算法生成 128bit 或者 256bit 的哈希值,如果校验有问题就要求重传
6. 注意点:
      绝不要以明文存储密码
      永远使用 哈希算法 来处理密码,绝不要使用 Base64 或其他编码方式来存储密码,这和以明文存储密码是一样的
      使用哈希,而不要使用编码。编码以及加密,都是双向的过程,而密码是保密的,应该只被它的所有者知道
      这个过程必须是单向的。哈希正是用于做这个的,从来没有解哈希这种说法, 但是编码就存在解码,加密就存在解密
      绝不要使用弱哈希或已被破解的哈希算法,MD5SHA1 ,只使用强密码哈希算法
      绝不要以明文形式显示或发送密码,即使是对密码的所有者也应该这样。如果你需要 “忘记密码” 的功能
      可以随机生成一个新的 一次性的(这点很重要)密码,然后把这个密码发送给用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
Last Updated: 2024/7/31 12:57:25
    飘向北方
    那吾克热-NW,尤长靖