分析
传统思路:
- •登陆⻚⾯把⽤⼾名密码提交给服务器.
- 服务器端验证⽤⼾名密码是否正确, 并返回校验结果给后端
- 如果密码正确, 则在服务器端创建 Session . 通过 Cookie 把 sessionId 返回给浏览器
问题:
集群环境下⽆法直接使⽤Session
原因分析:
我们开发的项⽬, 在企业中很少会部署在⼀台机器上, 容易发⽣单点故障. (单点故障: ⼀旦这台服务器挂 了, 整个应⽤都没法访问了). 所以通常情况下, ⼀个Web应⽤会部署在多个服务器上, 通过Nginx等进⾏负载均衡.此时, 来⾃⼀个⽤⼾的请求就会被分发到不同的服务器上.
假如我们使⽤Session进⾏会话跟踪, 我们来思考如下场景:
- ⽤⼾登录 ⽤⼾登录请求, 经过负载均衡, 把请求转给了第⼀台服务器, 第⼀台服务器进⾏账号密码 验证, 验证成功后, 把Session存在了第⼀台服务器上
- 查询操作 ⽤⼾登录成功之后, 携带Cookie(⾥⾯有SessionId)继续执⾏查询操作, ⽐如查询博客列 表. 此时请求转发到了第⼆台机器, 第⼆台机器会先进⾏权限验证操作(通过SessionId验证⽤⼾是否 登录), 此时第⼆台机器上没有该⽤⼾的Session, 就会出现问题, 提⽰⽤⼾登录, 这是⽤⼾不能忍受的
接下来我们介绍第三种⽅案: 令牌技术
令牌技术
令牌其实就是⼀个⽤⼾⾝份的标识, 名称起的很⾼⼤上, 其实本质就是⼀个字符串.
⽐如我们出⾏在外, 会带着⾃⼰的⾝份证, 需要验证⾝份时, 就掏出⾝份证
⾝份证不能伪造, 可以辨别真假
服务器具备⽣成令牌和验证令牌的能⼒
我们使⽤令牌技术, 继续思考上述场景:
- ⽤⼾登录 ⽤⼾登录请求, 经过负载均衡, 把请求转给了第⼀台服务器, 第⼀台服务器进⾏账号密码 验证, 验证成功后, ⽣成⼀个令牌, 并返回给客⼾端.
- 客⼾端收到令牌之后, 把令牌存储起来. 可以存储在Cookie中, 也可以存储在其他的存储空间(⽐如 localStorage)
- 查询操作 ⽤⼾登录成功之后, 携带令牌继续执⾏查询操作, ⽐如查询博客列表. 此时请求转发到了 第⼆台机器, 第⼆台机器会先进⾏权限验证操作. 服务器验证令牌是否有效, 如果有效, 就说明⽤⼾已 经执⾏了登录操作, 如果令牌是⽆效的, 就说明⽤⼾之前未执⾏登录操作
令牌的优缺点
优点:
- 解决了集群环境下的认证问题
- 减轻服务器的存储压⼒(⽆需在服务器端存储)
缺点:
需要⾃⼰实现(包括令牌的⽣成, 令牌的传递, 令牌的校验)
JWT令牌
令牌本质就是⼀个字符串, 他的实现⽅式有很多, 我们采⽤⼀个JWT令牌来实现.
介绍
JWT全称: JSON Web Token 官⽹: JSON Web Tokens - jwt.io
Token(JWT)是⼀个开放的⾏业标准(RFC 7519), ⽤于客⼾端和服务器之间传递安全可靠的 信息.
其本质是⼀个token, 是⼀种紧凑的URL安全⽅法.
JWT组成
JWT由三部分组成, 每部分中间使⽤点 (.) 分隔,⽐如:aaaaa.bbbbb.cccc
- Header(头部) 头部包括令牌的类型(即JWT)及使⽤的哈希算法(如HMAC SHA256或RSA)
- Payload(负载) 负载部分是存放有效信息的地⽅, ⾥⾯是⼀些⾃定义内容. ⽐如: {"userId":"123","userName":"zhangsan"} , 也可以存在jwt提供的现场字段, ⽐如 exp(过期时间戳)等. 此部分不建议存放敏感信息, 因为此部分可以解码还原原始内容.
- Signature(签名) 此部分⽤于防⽌jwt内容被篡改, 确保安全性. 防⽌被篡改, ⽽不是防⽌被解析.