后端基础day10 JWT鉴权登陆 | 青训营笔记

213 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 10 天

分布式Session

如果有多台服务器, 通过负载均衡机制, 则session可能只存在于一台中, 此时相当于session失效了.

解决方案:

  • session复制: 直接同步到所有session, 开销大
  • session粘滞: 用特定哈希策略使得用户的session每次都分配到一台服务器
  • session集中管理: 例如用Redis集中存储session, 所有服务器都从Redis中拿取

cookie禁用怎么办

cookie禁用之后就无法通过cookie捎带sessionID来跟踪会话了.

但是sessionID可以直接通过URL捎带: https://www.fifpoet.com/?session_id=xx

CSRF攻击

CSRF(Cross Site Request Forgery) ⼀般被翻译为 跨站请求伪造

  • Session-Cookie模式: 不能避免CSRF
  • Token: 可以避免CSRF

原因: cookie可以被黑客借用来执行用户不知情的操作, 但是不可以获取cookie中的具体内容. 如果cookie中加入token, 则会在请求时对比请求的和cookie中的token, 所以不可以伪造.

Referer字段

HTTP中的referer字段可以记录请求来源, 所以可以防止CSRF

缺点: ①有些旧浏览器可以修改referer字段 ②用户隐私泄露问题

JWT

JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。

原理

组成

JWT是一个用点分隔的字符串(形如xxxxx.yyyyy.zzzzz), 用户信息全部存在JWT中, 是noSession的模式

  • Header (json): 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
  • Payload (json): 用来存放实际需要传递的数据
  • Signature (base64) :服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

验证过程

  1. 用户发送登陆请求
  2. 如果校验正确的话,服务端会返回已经签名的 Token,也就是 JWT. 此时jwt会存在本地的localStorage(推荐, 防止CSRF)或cookie中
  3. 用户以后每次向后端发请求都在 Header 中带上这个 JWT 。
  4. 服务端检查 JWT 并从中获取用户相关信息。

JWT使用建议

  • 使用安全系数高的加密算法。
  • JWT 存放在 localStorage 中而不是 Cookie 中,避免 CSRF 风险。
  • 一定不要将隐私信息存放在 Payload 当中。
  • 密钥一定保管好,一定不要泄露出去。JWT 安全的核心在于签名,签名安全的核心在密钥
  • Payload 要加入 exp (JWT 的过期时间),永久有效的 JWT 不合理。并且,JWT 的过期时间不易过长。

优势

  • 无状态性, 服务端免去了存储session的开销
  • 避免CSRF攻击
  • 单点登录 友好(只需采用同一套token验证)

问题和解决办法

注销

问题根源: JWT 一旦被发放出去就会一直存在到有效期终止

所以如果想要注销 / 修改密码 / 封禁用户, 则比较难解决

  1. JWT存入Redis: 如果JWT失效则查询并删除
  2. Redis黑名单: 在Redis中维护一个JWT黑名单, 适用于JWT失效较少的情况
  3. 保持JWT有效期短

续签

场景: 在登录了页面之后, 用户正在填写大量的表单, 但是提交的时候发现JWT过期了!!

  1. 快过期了返回新JWT, 客户端每次比较新旧JWT.
  2. JWT有效期设置到半夜.
  3. JWT: 保持一个AccessJWT(时间短), RefreshJWT(时间长). 第一次请求获取两个JWT存在本地, AccessJWT过期时若RefreshJWT未过期则返回新AccessJWT.