使用到的技术:
- 前端使用 React + Webpack + CSS modules + Redux Toolkit,管理端使用 React + AntD + Redux Toolkit
- 后端使用 Koa + Sequelize + MySQL
- 身份验证使用 JWT
- 文章渲染使用 marked + highlight
- 服务器部署使用 nginx + PM2
使用同构渲染的方式进行首屏加载优化
使用 Webpack SplitChunks 进行代码拆分
JWT
JWT 是一个用来作为 JSON 对象在各方之间安全传输信息的标准。
原理:
服务器认证之后,生成一个 JSON 对象,发回给用户,大致结构
{
"姓名": "showbuger",
"角色": "管理员",
"过期时间": "xxxx"
}
以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名
服务器就不用保存任何 session 数据了,也就是说,服务器变成无状态的了,从而比较容易实现扩展
数据结构
一个很长的字符串,通过 **.**
分隔成三个部分。
JWT 的三个部分:Header(头部)、Payload(负载)、Signature(签名)。Header.Payload.Signature
Header 是一个 JSON 对象,描述 JWT 的元数据
{
"alg": "HS256", // 代表签名的算法,默认是 HMAC SHA256
"type": "JWT" // 表示这个 token 的类型
}
最后,将上面的 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三个部分拼接成一个字符串,用 .
连接,返回给用户。