这是我参与「第五届青训营 」伴学笔记创作活动的第 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)生成。
验证过程
- 用户发送登陆请求
- 如果校验正确的话,服务端会返回已经签名的 Token,也就是 JWT. 此时jwt会存在本地的localStorage(推荐, 防止CSRF)或cookie中
- 用户以后每次向后端发请求都在 Header 中带上这个 JWT 。
- 服务端检查 JWT 并从中获取用户相关信息。
JWT使用建议
- 使用安全系数高的加密算法。
- JWT 存放在 localStorage 中而不是 Cookie 中,避免 CSRF 风险。
- 一定不要将隐私信息存放在 Payload 当中。
- 密钥一定保管好,一定不要泄露出去。JWT 安全的核心在于签名,签名安全的核心在密钥。
- Payload 要加入
exp(JWT 的过期时间),永久有效的 JWT 不合理。并且,JWT 的过期时间不易过长。
优势
- 无状态性, 服务端免去了存储session的开销
- 避免CSRF攻击
- 单点登录 友好(只需采用同一套token验证)
问题和解决办法
注销
问题根源: JWT 一旦被发放出去就会一直存在到有效期终止
所以如果想要注销 / 修改密码 / 封禁用户, 则比较难解决
- JWT存入Redis: 如果JWT失效则查询并删除
- Redis黑名单: 在Redis中维护一个JWT黑名单, 适用于JWT失效较少的情况
- 保持JWT有效期短
续签
场景: 在登录了页面之后, 用户正在填写大量的表单, 但是提交的时候发现JWT过期了!!
- 快过期了返回新JWT, 客户端每次比较新旧JWT.
- JWT有效期设置到半夜.
- 双 JWT: 保持一个AccessJWT(时间短), RefreshJWT(时间长). 第一次请求获取两个JWT存在本地, AccessJWT过期时若RefreshJWT未过期则返回新AccessJWT.