Session Cookie 与 JWT 认证方式对比

认证

理解 Session Cookie 概念前,我们需要先了解下 HTTP 协议的特点。HTTP 是无状态协议,用于传输数据。 它启用了客户端和服务器端之间的通信。 最初是为了在Web浏览器和Web服务器之间建立连接而建立的。

注意:HTTP 是无状态的。什么叫无状态?比如你在上网冲浪,某购物平台买东西,当你将商品加入购物车时,切换到另一个页面,购物车的东西就消失了。因为每次 HTTP 请求对于服务端来说都是新的,服务端并不知道你是谁。

那有没有办法解决这个问题呢?聪明如你,如果我第一次请求后,服务端给我一个 key,每次提交请求带上它,那服务端是不是就知道我是谁了呢?Session Cookie 其实就是基于这样的设计。

我们来看一下基于 Session 的认证机制。

Session Cookie 认证方式

  1. 用户使用用户名密码登录网站。服务端生成 Session 放到内存中。
  2. 服务端往浏览器里设置 session-id (相当于上文提到的 key,唯一性由服务端保证)
  3. 客服端(指浏览器)向服务端发起获取用户数据请求,并携带 Cookie。
  4. 服务端通过 session-id 查找对应 Session ,找到即返回数据。

写到这里,有同学可能会问了,单体应用这样实现没有问题。如果应用要做负载均衡,物理机甚至都不在一起,这种情形下怎么维护 Session 呢?

在笔者实际参与的项目中,比如 Laravel 项目,我们通常会把 Session 放到 Redis 存储,多个应用使用同一个 DB,这样也是一种解决办法。

那有没有其他的方式呢?有,我们可以不是用 Session Cookie 这种结构,下面介绍一下 JWT (JSON Web Token)。

JWT 认证方式

  1. 用户使用用户名密码登录到服务器,服务器为用户创建 JWT。
  2. 服务器响应 JWT ,客户端将其存在 Local Storage 下。
  3. 客户端发起数据请求,通过在 HTTP 头部设置 JWT ,随请求到服务端。
  4. 服务端使用私钥去解密 JWT,通过即响应请求数据。

JWT 由三部分组成

  • Header 头部,描述 JWT 元数据
  • Payload 载荷,实际传输数据,可以是业务数据。
  • Signature 签名,是对前两部分的签名,防止数据篡改。

JWT

使用 JWT 相当于服务端把 Session 数据的维护由服务端转移到客户端。服务端不需要额外的存储,每次验证只要校验 JWT 是否合法即可,减少服务端的存储压力。

但 JWT 有这么完美么?恐怕不一定,笔者在整理这篇文章时,发现有人就不同意。

大家可以看看这篇文章:Stop using JWT for sessions 其中列举了 JWT 的一些缺陷。

这里简单提一下:

  • 占用较多的空间。每次请求都要携带 JWT base64 编码的内容。
  • 没有办法主动使一个 JWT 失效,除了它自己过期了。
  • 数据过时问题,在 JWT 失效前,其中 Payload 数据可能会过时。

总结:使用哪种方还是需要看具体的业务场景,不要盲目跟风。

参考

updatedupdated2021-03-072021-03-07
Load Comments?