浏览器登录态保存方案

  • Cookie 是由服务器发出,并由浏览器保存的一小块数据(大概 4kb 大小),浏览器再下一次请求同一个服务器时,会携带 cookie。
  • 通过 cookie 可以使浏览器的访问变得有状态,但是由于数据只保存在浏览器中,因此状态是单向的,服务器无法验证。

什么是 session

  • Session 是另一种记录服务器和浏览器会话状态的机制。Session 这种机制基于 Cookie 来实现
  • Session 的状态数据存储在服务器端,浏览器通过 Cookie 保存了一个 SessionId

Session 认证流程

  1. 用户向服务器提交用户名和密码
  2. 服务器收到并验证成功后,生成一个 session(其实就是一段数据,比如包含 userId,userName 等)保存在内存或者数据库中
  3. 服务器返回给用户一个 session_id,写入用户的 cookie
  4. 用户后面的每一次访问,都会通过 Cookie 将 session_id 传回服务器
  5. 服务器收到 session_id 找到之前保存的数据,由此得知用户身份,继而执行操作
  6. 如果没有找到数据,则可以重定向至登陆页。

session 的问题

  • 如果是一个服务器集群,就需要共享 session 数据
  • 如果 AB 网站需要单点登录共享登录态,也需要共享 session 数据

什么是 JWT json web token

JWT 是另一种保存状态的方案,和 Session 的区别是,JWT 只需要浏览器保存就可以了,服务器不需要在维护 session 数据。
JWT 会在浏览器端保存哪些数据呢?其实还是类似 userId,userName 等数据。
但是直接保存明文数据肯定是不行的,需要保存加密之后的数据。

将数据加密成一个字符串。中间用.分割成 3 部分。分别为

  • Header 头部
    一个对象,描述 JWT 的元数据,也就是这个 JWT 是什么格式呀,用了什么加密算法(HS256)呀。比如
    { "alg": "HS256", "typ": "JWT" }
    这个对象使用 Base64URL 算法转换成字符串

  • Payload 负载(数据)
    也是一个对象保存各种数据。最后也是使用 Base64URL 算法转换成字符串

  • Signature 签名
    签名的作用主要是验证 Header 和 Payload,防止它们被篡改,服务器会保存 Signature 的密钥,使用密钥对 Header 和 Payload 进行 SHA256 加密。
    浏览器再次请求时,服务器通过密钥对 Header 和 Payload 解密,然后和 Signature 对比,验证数据是否被篡改。以及是否有效。

最终组成 Header.Payload.Signature这样的一个字符串,类似于

JWT token

客户端收到 JWT 后,可以保存在 cookie 里面,也可以保存在 localStorage 里面。
后面的请求时,可以随着 cookie 一起发送,但是会有跨域问题,所以也可以放在 Http 的 Header 里面。
例如:Authorization: Bearer <token>

JWT 的优点

  • 相比于 Session,JWT 不需要服务器在维护 session 数据了,全部的数据都放在了浏览器上。
  • 但是验证的时候需要做解密的操作,牺牲了一定的 CPU 性能。

JWT 的缺点

  • 一旦签发了某个 Token,服务器无法作废它,因为服务器只会验证它,除非还有额外的逻辑来处理。
  • 由于不好作废它,那么一旦 Token 被盗用,就会一直有效,因此 token 的有效期最好不要太长。
  • 应该使用 Https,保证 token 的安全性