使用到的技术:

  • 前端使用 React + Webpack + CSS modules + Redux Toolkit,管理端使用 React + AntD + Redux Toolkit
  • 后端使用 Koa + Sequelize + MySQL
  • 身份验证使用 JWT
  • 文章渲染使用 marked + highlight
  • 服务器部署使用 nginx + PM2

使用同构渲染的方式进行首屏加载优化
使用 Webpack SplitChunks 进行代码拆分

JWT

JWT 是一个用来作为 JSON 对象在各方之间安全传输信息的标准。

原理:

服务器认证之后,生成一个 JSON 对象,发回给用户,大致结构

  1. {
  2. "姓名": "showbuger",
  3. "角色": "管理员",
  4. "过期时间": "xxxx"
  5. }

以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名
服务器就不用保存任何 session 数据了,也就是说,服务器变成无状态的了,从而比较容易实现扩展

数据结构

一个很长的字符串,通过 **.**分隔成三个部分。
JWT 的三个部分:Header(头部)、Payload(负载)、Signature(签名)。Header.Payload.Signature
image.png
Header 是一个 JSON 对象,描述 JWT 的元数据

  1. {
  2. "alg": "HS256", // 代表签名的算法,默认是 HMAC SHA256
  3. "type": "JWT" // 表示这个 token 的类型
  4. }

最后,将上面的 JSON 对象使用 Base64 URL 算法转成字符串

Payload 也是一个 JSON 对象,用来存放实际需要传递的数据。
JWT规定了7个官方字段:

  • iss(issuer):签发人
  • exp(expiration time):过期时间
  • sub(subject):主题
  • aud(audience):受众
  • nbf(not before):生效时间
  • iat(Issued At):签发时间
  • jti(JWT ID):编号

除此之外,还可以在这个部分自定字段
这个 JSON 对象也要通过 Base64URL 算法转成字符串
JWT 默认是不加密的,任何人都可以读到,所以不要把隐私信息放在这个部分。这里的理解是,最终生成的 token 是可以被所有人都访问到

Signature 是对前两部分的签名,防止数据篡改
首先,需要指定一个密钥,这个密钥只有服务器才知道,不能泄露给用户。然后使用 Header 中指定的签名算法,算出签名
公式: HMACSHA256( base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)
算出签名后, 把 Header、Payload、Signature三个部分拼接成一个字符串,用 . 连接,返回给用户。

流程

  1. 用户使用用户名密码请求服务器
  2. 服务器进行验证用户信息
  3. 通过验证后发送给用户一个 token
  4. 客户端存储 token,并在每次请求时附送上这个 token 的值
  5. 服务端验证 token 值,并返回数据

    同构渲染(SSR)

    同构就是一套代码先在服务端跑一遍,再在客户端跑一遍

    Webpack Splitchunks