什么是 Cookie
- Cookie 是由服务器发出,并由浏览器保存的一小块数据(大概 4kb 大小),浏览器再下一次请求同一个服务器时,会携带 cookie。
- 通过 cookie 可以使浏览器的访问变得有状态,但是由于数据只保存在浏览器中,因此状态是单向的,服务器无法验证。
什么是 session
- Session 是另一种记录服务器和浏览器会话状态的机制。Session 这种机制基于 Cookie 来实现
- Session 的状态数据存储在服务器端,浏览器通过 Cookie 保存了一个 SessionId
Session 认证流程
- 用户向服务器提交用户名和密码
- 服务器收到并验证成功后,生成一个 session(其实就是一段数据,比如包含 userId,userName 等)保存在内存或者数据库中
- 服务器返回给用户一个 session_id,写入用户的 cookie
- 用户后面的每一次访问,都会通过 Cookie 将 session_id 传回服务器
- 服务器收到 session_id 找到之前保存的数据,由此得知用户身份,继而执行操作
- 如果没有找到数据,则可以重定向至登陆页。
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 后,可以保存在 cookie 里面,也可以保存在 localStorage 里面。
后面的请求时,可以随着 cookie 一起发送,但是会有跨域问题,所以也可以放在 Http 的 Header 里面。
例如:Authorization: Bearer <token>
JWT 的优点
- 相比于 Session,JWT 不需要服务器在维护 session 数据了,全部的数据都放在了浏览器上。
- 但是验证的时候需要做解密的操作,牺牲了一定的 CPU 性能。
JWT 的缺点
- 一旦签发了某个 Token,服务器无法作废它,因为服务器只会验证它,除非还有额外的逻辑来处理。
- 由于不好作废它,那么一旦 Token 被盗用,就会一直有效,因此 token 的有效期最好不要太长。
- 应该使用 Https,保证 token 的安全性