浅析 JWT

444 阅读3分钟

J.W.T 分别是什么意思

  • J: JSON
  • W: web
  • T: token

陌生的 token

很多没接触过后端的前端,总是很不理解 token 是什么意思,这里给一个很直接的解释:token 就是加密的字符串

  • 如果我给用户一个字符串,内容是 "1",它算 token,因为你不知道我的 "1" 是加密之后还是加密之前的
  • 如果我的字符串是 128 位字符,这也算 token
  • 因为我们不知道这个字符串加没加过密,只要是字符串我们都可以认为是 token
  • 所以现在再简化:token 就是字符串

Web 登陆

前置知识:Session & Cookie

前端耳熟能详解决登陆的方案是:Session + Cookie

Cookie

CookieHPPT 协议的一个东西,但凡你用 HTTP 你都可以用到 Cookie

它的功能是:由 服务器客户端/浏览器 发的一段 token,这个 token 就是 Cookie

虽然 服务器浏览器 那么多字符串,但 Cookie 这个 token 特殊在:必须在后续的所有请求中自动带上

也就是说,在后续的所有请求的 header 里必须带上这么一个字段,叫做 Cookie: token

当然它还有很多细则,但这里只讲它最精髓的一部分,就是:服务器 发一个 字符串 给浏览器,浏览器以后每向同一个域名的服务器发请求的时候,都必须在请求头里面带上这个 token,只要满足这个特征的字符串,就叫做 Cookie

Session

uid 存到内存,把 key 发给前端

Session 实际上就是:服务器 发给 浏览器 一个东西,比如这个东西是 uid 用于识别用户,这就可以识别请求来自哪个用户,因为 HTTP 的服务器是无状态的,它根本区分不出来每个用户的请求有什么区别,必须有一点点不同,这个不同就是 Cookie 不同

但是,黑客可以把上面的 uid=1 改为 uid=2 发送给 服务器服务器 并不知道有没有被改,服务器只看都一个 token,这就造成了 用户身份伪造 的攻击,这是使用明文的 Cookie 造成的问题

那这样子的话,我们就使用密文的 Cookie:比如 服务器 给「用户 1」发送 "xxxxx......" 128 位的字符串,给「用户 2」发送 "yyyyy......" 128 位的字符串,

服务器 把对应的信息写在 服务器 的内存或文件,这样就能分辨出对应的用户了,而用户猜不出其他的 uid 是什么,这样就解决了:服务器 每个 Cookie 对应哪个用户,而用户不知道用户对应的 Cookie 是什么

所以,这个东西就是 Session

但是这还有问题:因为这是要保存在内存或文件上面,而这是要占用服务器资源的,而 JWT 是用另一种不同的思路来做同一种事情

假设我们要做的事情是:认证用户身份

JWT 的定义

就是把 uid 加密给传给前端

JWT 由 3 部分组成:Header(头)、Payload(体)、Signature(签名/密文)

  • Header

    • "alg": 需要标记当前加密算法是什么
    • "typ": 使用的类型
  • Payload: 这里就是真正的 JSON,同时也有其他内置字段

  • Signature

    一种加密方式(私钥, base64(header), base64(body))
    

最终 token 就是:Header + "." + Payload + "." + Signature

JWT 的使用

前端:

  1. 拿到 JWT,存在 localStorage
  2. 配置请求库(axios) header 带上 JWT
  3. 发请求

后端:

  1. 看 header 有没有 JWT
  2. 解密:把 Signature 部分的解密出来的 uid 和 Payload 部分的 uid 是否一样
  3. 如果一样的话就去读数据库,把对应内容发给前端

这样子,前端知道 uid 是什么,但是不能够改

以上,就是我对 JWT 粗略的理解