前端鉴权背景

原因:http请求无状态





鉴权方式

1. 初窥:前端全局变量、sessionStorage、localStorage

a. 利弊

  1. 全局变量不利于持久化, 一刷新页面就没有
  2. sessionStorage、localStorage虽可以持久化,但操作麻烦,要前端存、前端手动带上给服务端

2. 基础:前端存储cookie

a. 介绍

相比sessionStorage、localStorage等本方式,借助 HTTP 头、浏览器能力,cookie 可以做到前端无感知

b. 原理

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

2. 方案一:服务端session

a. 介绍

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

b.服务端存储

  1. redis: 内存型数据库,性能好
  2. mysql: 性能不高
  3. 应用内存: 重启就没了

c.问题

  1. 服务端存放session
  2. 分布式存储session

3. 方案二:token

a. 介绍

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

b. 步骤

  1. 存储方式: 前端cookie
  2. 存储内部: 被编码过的有效期、使用现在、用户信息

c. 编码

  1. base64
  2. 签名防篡改

d. 问题

  1. 新增cookie数量
  2. cookie格式没有规范

    4. 方案三:jwt

    a. 介绍和格式

    jwt(json web token)是一个开放标准,定义了一种传递 JSON 信息的方式。这些信息通过数字签名确保可信。

b. 原理

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

c. session和token的区别

  1. session:我们通常认为 session 是「种在 cookie 上、数据存在服务端」的认证方案
  2. token: token 是「客户端存哪都行、数据存在 token 里」的认证方案

5. sso (单点登录)

a. 介绍

一次登录,全线通用」的能力,叫做「单点登录」

b. “假的”单点登录

如果业务系统都在同一主域名下,比如wenku.baidu.com、tieba.baidu.com,就好办了。可以直接把 cookie domain 设置为主域名 baidu.com,百度也就是这么干的

c. “真实”单点登录

a.com、b.com、c.com一次登录, 全系统可用

  1. 用户进入 A 系统,没有登录凭证(ticket),A 系统给他跳到 SSO
  2. SSO 没登录过,也就没有 sso 系统下没有凭证(注意这个和前面 A ticket 是两回事),输入账号密码登录
  3. SSO 账号密码验证成功,通过接口返回做两件事:一是种下 sso 系统下凭证(记录用户在 SSO 登录状态);二是下发一个 ticket
  4. 客户端拿到 ticket,保存起来,带着请求系统 A 接口
  5. 系统 A 校验 ticket,成功后正常处理业务请求
  6. 此时用户第一次进入系统 B,没有登录凭证(ticket),B 系统给他跳到 SSO
  7. SSO 登录过,系统下有凭证,不用再次登录,只需要下发 ticket
  8. 客户端拿到 ticket,保存起来,带着请求系统 B 接口

d. 完整版sso

  1. 在 SSO 域下,SSO 不是通过接口把 ticket 直接返回,而是通过一个带 code 的 URL 重定向到系统 A 的接口上,这个接口通常在 A 向 SSO 注册时约定
  2. 浏览器被重定向到 A 域下,带着 code 访问了 A 的 callback 接口,callback 接口通过 code 换取 ticket
  3. 这个 code 不同于 ticket,code 是一次性的,暴露在 URL 中,只为了传一下换 ticket,换完就失效
  4. callback 接口拿到 ticket 后,在自己的域下 set cookie 成功
  5. 在后续请求中,只需要把 cookie 中的 ticket 解析出来,去 SSO 验证就好
  6. 访问 B 系统也是一样

鉴权总结

1. HTTP 是无状态的,为了维持前后请求,需要前端存储标记
4. token 是另一种状态管理方案,相比于 session 不需要后端存储,数据全部存在前端,解放后端,释放灵活性
5. token 的编码技术,通常基于 base64,或增加加密算法防篡改,jwt 是一种成熟的编码方案
6. 在复杂系统中,token 可通过 service token、refresh token 的分权,同时满足安全性和用户体验
7. session 和 token 的对比就是「用不用cookie」和「后端存不存」的对
8. 单点登录要求不同域下的系统「一次登录,全线通用」,通常由独立的 SSO 系统记录登录状态、下发 ticket,各业务系统配合存储和认证 ticket

文章来源于