这次让大家彻底明白JWT的前世今生

前言

故事还要从500年前说起

http出生了,孩子可爱至极,人见人爱,可是缺少一个重要零部件,那就是,他是无状态的,也就是说他是天生脸盲,分不清爹和隔壁老王。这真是一个头疼的问题呀

也就是说http不知道当前用户是谁。

但是总不能让用户登录了,跳转一个页面又登录吧。

我们以前是如何处理这种问题的呢?

先看下一般的认证流程,基于 session_idCookie 实现

  • 用户向服务器发送用户名和密码。
  • 服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
  • 服务器向用户返回一个 session_id,写入用户的 Cookie
  • 用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
  • 服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。

SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

看起来挺麻烦的哈,而且有很多的局限性,到底是因为哪些局限性从而促进了jwt的诞生呢?

  1. 服务端压力增大:每个用户通过认证之后都会将session数据保存在服务端,而随着用户增多,服务器压力增大
  2. csrf攻击:session是依赖于cookie的,cookie如果被截获了,那么就会造成csrf攻击(jwt不依赖于cookie,jwt在本地存储)
  3. 扩展性不强:如果将来搭建了多个服务器,虽然每个服务器都执行的是同样的业务逻辑,但是session数据是保存在内存中的(不是共享的),用户第一次访问的是服务器1,当用户再次请求时可能访问的是另外一台服务器2,服务器2获取不到session信息,就判定用户没有登陆过。

基于这些局限性,诞生了jwt

jwt是什么?

JWT(JSON Web Token)可用于Web应用程序和API的身份验证和授权目的,它们被广泛用作无状态身份验证的标准,因为它们消除了服务器端会话的需要。 JWT易于实施并且与平台无关,因此在Web开发人员中很受欢迎。

什么是无状态身份验证?

正因为jwt可以进行无状态身份验证,才让他成为了标准,坐稳了帝位。解决了传统验证方式的所有局限性,你掌握了无状态身份验证也就掌握了本节内容接下来我们就围绕无状态身份验证来说一下

无状态身份验证是指服务器在进行用户身份验证时不需要存储任何会话信息或状态信息,完全基于 JWT 进行验证和授权。

传统的身份验证方式通常涉及到会话管理,服务器需要存储用户的会话信息,比如用户登录状态、权限等。这导致服务器需要维护会话状态并存储相关信息,增加了服务器的复杂性和开销。

而使用 JWT 进行无状态身份验证,服务器在用户登录成功后,会生成一个 JWT,将用户的身份信息(如用户ID、角色等)以及其他必要的信息(如过期时间、签名等)封装在 JWT 中,并将 JWT 发送给客户端。客户端在后续的请求中将 JWT 作为身份凭证发送给服务器。

服务器在接收到 JWT 时,通过验证 JWT 的签名,并解析其中的信息,即可确定用户的身份和权限。由于 JWT 中已经包含了用户的身份信息,服务器无需存储会话信息,因此可以轻松地进行水平扩展,提高了系统的可伸缩性和性能。

无状态身份验证的特点有:

  1. 无需存储会话信息:服务器不需要在内存或数据库中存储任何会话信息,减轻了服务器的负担。
  2. 节省资源:不需要进行会话状态的检查和管理,减少了服务器的开销。
  3. 可伸缩性:服务器可以轻松地进行水平扩展,因为每个请求都是独立的,服务器无需维护会话状态。
  4. 安全性:JWT 使用数字签名验证其完整性和真实性,防止伪造和篡改。

jwt是如何做到无状态的

JWT实现无状态身份验证的关键在于将用户的身份信息和其他必要的信息封装在JWT中,并在每个请求中将JWT作为身份凭证发送给服务器。服务器在接收到JWT后,通过验证JWT的签名和解析其中的信息,即可确定用户的身份和权限。

具体来说,JWT实现无状态身份验证的过程如下:

  1. 用户登录:用户提供有效的凭证(如用户名和密码),服务器验证凭证的有效性。

  2. 生成JWT:服务器在用户登录成功后,生成一个JWT。JWT由三部分组成:头部(Header)、负载(Payload)和签名(Signature)。

    • 头部:头部指定了JWT的类型(typ)和所使用的签名算法(alg)。
    • 负载:负载包含了用户的身份信息(如用户ID、角色等)和其他必要的信息(如过期时间、发布时间等)。
    • 签名:签名是对头部和负载进行签名的结果,使用服务器端的密钥进行签名。

负载结构如下

json 复制代码
{
  "姓名": "王二",
  "角色": "管理员",
  "到期时间": "2023年8月31日0点0分"
}

jwt流程图

  1. 发送JWT:服务器将生成的JWT发送给客户端,可以通过HTTP的响应头或者放在响应的主体中。

  2. 客户端存储JWT:客户端接收到JWT后,可以将其存储在本地(如浏览器的localStorage)。

  3. 请求携带JWT:客户端在后续的请求中,将JWT作为身份凭证添加到请求的头部(通常是Authorization头)中。

  4. JWT验证:服务器在接收到请求时,从请求的头部中获取JWT,并验证JWT的签名的有效性。如果签名验证通过,服务器会解析JWT的负载,获取用户的身份信息和其他相关信息。

  5. 身份验证和授权:服务器根据JWT中的信息确定用户的身份和权限,并进行相应的身份验证和授权操作。

通过将用户的身份信息封装在JWT中,并在每个请求中发送JWT作为身份凭证,服务器可以在无需存储会话信息的情况下进行身份验证和授权。这样就实现了无状态身份验证,减轻了服务器的负担,提高了系统的可伸缩性和性能。

jwt的安全

还有一点需要讲的就是jwt的安全,因为jwt里面包含认证信息,如果一旦被盗用,损失会很大

JWT 的安全

  • JWT 默认是不加密,但也是可以加密的。JWT 不加密的情况下,不能将秘密数据写入 JWT
  • JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证
  • 为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输

总结🤔

  1. 今天我们讲了通过cookiesession_id构成的传统登录方式,并讲了这种登录方式的局限性
  2. 因为传统登录方式的局限性,才诞生了jwtjwt是一种无状态身份验证。然后我们讲了什么是无状态身份验证,以及jwt是如何实现无状态身份验证的
  3. 最后我们讲了一下jwt的安全,因为jwt里面包含认证信息,如果一旦被盗用,损失会很大

参考

相关推荐
Boilermaker19925 分钟前
【Java EE】SpringIoC
前端·数据库·spring
中微子16 分钟前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上102431 分钟前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y1 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁1 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry1 小时前
Fetch 笔记
前端·javascript
拾光拾趣录1 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟1 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan1 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构