jwt/token与cookie/session的区别

301 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

简介

三者都是应用在 web 中对 http 无状态协议的补充,达到状态保持的目的。

一、cookie/session

1、认证方式

  • 用户输入用户名和密码,发送给服务器。
  • 服务器验证用户名和密码,正确的话就创建一个会话(session),同时会把这个会话的 ID 回传给客户端的浏览器中,因为保存的地方是浏览器的 cookie,所以这种认证方式叫做 基于 cookie 的认证方式
  • 后续的请求中,浏览器会发送会话ID(请求头中携带cookie)到服务器,服务器上如果能找到对应 session_id 的会话,那么服务器就会正常返回数据给浏览器。
  • 用户退出登录,sesstion 会话会同时在客户端和服务端销毁。

2、优点

  • 结构简单:包含简单的键值对
  • 数据持久:虽然客户端上 cookie 的持续时间取决于过期处理和用户干预,cookie 通常是客户端上持续时间最长的数据保留形式。

3、缺点

  • 大小受到限制。
  • 非常不安全:cookie将数据裸露在浏览器中,这样大大增加了数据被盗取的风险。我们不应该将重要的数据放在 cookie 中,或者将数据加密处理。
  • 服务器需要为每个用户保留 session 信息,连接用户过多会造成服务器内存压力过大
  • 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还得在这台服务器上才能拿到授权的资源。这样在分布式应用上,会限制负载均衡和集群水平拓展的能力。

二、token

1、token 的认证过程

  • 用户输入用户名和密码,发送给服务器。
  • 服务器验证用户名和密码,正确的话就返回一个签名过的 tokentoken 可以认为就是个长长的字符串),浏览器拿到这个 token
  • 后续每次请求中,浏览器会把 token 作为请求头发送给服务器,服务器验证签名是否有效,如果有效则正常返回数据
  • 一旦用户退出登录,只需要客户端销毁 token 即可,服务端不需要任何操作

2、token 认证的特点

这种方式让 token(用户信息)存储在客户端中;服务端不需要存储这些信息,而只负责验证,不必进行数据库查询,执行效率提高的同时降低了服务端的压力。

三、JWT

JWT 是 json web token 的缩写。它将用户信息加密到 token 里,服务器不保存任何用户信息,只需要验证。

优点是在分布式系统中,很好地解决了单点登录问题,很容易解决了 session 共享的问题。JWT 长度较小,且可以使用 URL 传输。

不像 cookie 只能在 web 环境中起作用。JWT可以同时在多端使用。

JWT组成

JWT包含三个部分:Header头部、Payload载荷、Signature签名。

Header

Header通常包含了两部分:

  • type:代表 token 的类型,这里使用的JWT类型
  • alg:使用的加密算法类型

Payload

token 的第二部分是载荷信息,它包含一些实体的描述,通常是一个 User 信息

Signature

使用 header 中指定的算法将编码后的 header 、编码后的 payload、一个 secret 进行加密。

第三段 = 头部 + 载荷 + secret(加盐加密)

优点

  • 因为 json 的通用性,jwt可以支持跨语言请求。
  • 便于传输:构成非常简单,字节占用很小。
  • 不需要服务端保存会话信息,利于服务器横向拓展

缺点

无法作废已颁发的令牌/不易应对数据过期。

  • 登录状态信息续签问题。

比如设置 token 的有效期是一小时,那么一小时后如果用户仍然在这个 web 应用上,这个时候当然不能指望用户再登录一次。

目前可用的解决方案是在每次用户发出请求后都返回一个新的 token,前端再用这个新的 token 来替代旧的,这样每一次请求都会刷新 token 的有效期。

但是这样需要频繁的生成 token。另一种方案是判断还有多久这个 token 会过期,在 token 快要过期的时候,返回一个新的 token

  • 用户主动注销

JWT并不支持用户主动退出登录,客户端在别处使用 token 仍然可以正常访问。为了支持注销,一种解决方案是在注销时将该 token 加入到服务器的 redis 黑名单中。

四、OAuth与JWT的区别

OAuth2是一种授权框架:在使用第三方账号登录的时候。(比如使用微信、github登录某个应用)

JWT是一种认证协议:用在前后端分类,需要简单的对后台API进行保护时使用。