由于同学们报名的热情太高涨,打卡任务被张老师改成了两天一打,说实话压力还是蛮大的。本想写道算法题完成打卡,点开 GitHub 第三方登录时,对其中的原理产生了兴趣,对其中的常见概念进行了简单的学习与记录,由于时间紧促难免存在理解不到位。

  由于 Http 具有无状态性,因此一般使用 Cookie & Session 保存用户的登录状态。

验证流程

  1. 用户向服务器发送用户名和密码。
  2. 服务器验证用户提交的用户名和密码,将当前用户的信息和状态保存到 Session 生成对应的 Session id,保存到浏览器 Cookie 中。
  3. 用户此后的请求中携带着包含 Session id 的 Cookie。
  4. 服务器根据 Session id 读取相应的 Session。

  使用 Cookie & Session 虽然解决了用户状态问题但存在着一些弊端。

弊端

  1. 需要在服务器端保存大量数据,不利于服务器的水平扩展。
  2. 易遭受跨域攻击。

Token

  由于 Session 的弊端,Token 将用户状态保存在客户端中,认证流程与使用 Cookie & Session 方式相似。

验证流程

  1. 用户向服务器发送用户名和密码。
  2. 服务器验证用户提交的用户名和密码,将用户信息加密生成 Token 返回给用户,用户将其存储 localstorage 等容器中。
  3. 用户下次请求时将 Token 放入 Header、Body 、URL 中的一种。
  4. 服务器将用户传来的 Token 解密,就可以确定用户的身份了。

优势

  1. 可以用于 Restful API 中。
  2. 以时间(Token 解密)换取空间(Session),解决了水平扩展的问题。
  3. 可以抵御跨域攻击。

JWT(JSON Web Token)

  JWT 是一种 Token 的实现标准(RFC 7519),JWT 由三部分组成。

Header(头部)

1
2
{"typ": "JWT",
"alg": "HS256"}
  1. typ:Token 的类型(type)。
  2. alg: 签名算法(algorithm),默认使用 HMAC SHA256,缩写为 HS256。

Payload(负载)

1
2
3
{"iss":"joe",
"exp":1300819380,
"http://example.com/is_root":true}

  RFC 7519 规定了七种保留字段以供选用,除此以外可以自行定义。

  1. iss: 签发人(Issuer)。
  2. sub: 主题(Subject)。
  3. aud: 受众(Audience)。
  4. exp: 过期时间(Expiration Time)。
  5. nbf: 生效时间(Not Before)。
  6. iat: 签发时间(Issued At)。
  7. jti: 唯一编号(JWT ID)。

Signature(签名)

  首先对 Header 和 Payload 进行 Base64Url 编码,指定一个密钥(secret),使用 Header 中的加密算法产生密钥。

1
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

  算出 Signature 后以Header.Payload.Signature格式组成 JWT。

弊端

  1. JWT 一旦泄露,所有人都能获取到其全部权限。
  2. 服务端无法注销 Token,只能等待过期。