JWT 还能这样的去理解嘛??

news2025/1/15 6:26:47

其他系列文章目录

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章目录

文章目录

一、什么是 JWT?

二、JWT 由哪些部分组成?

2.1Header

2.2Payload

2.3Signature

三、如何基于 JWT 进行身份验证?

四、如何防止 JWT 被篡改?

五、如何加强 JWT 的安全性?

六、JWT 的优势

6.1无状态

6.2有效避免了 CSRF 攻击

6.3适合移动端应用

6.4单点登录友好

七、JWT 身份认证常见问题及解决办法

7.1注销登录等场景下 JWT 还有效

八、JWT 的续签问题


一、什么是 JWT?

JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。 从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token

JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。

可以看出,JWT 更符合设计 RESTful API 时的「Stateless(无状态)」原则

并且, 使用 JWT 认证可以有效避免 CSRF 攻击,因为 JWT 一般是存在在 localStorage 中,使用 JWT 进行身份验证的过程中是不会涉及到 Cookie 的。


二、JWT 由哪些部分组成?

JWT 本质上就是一组字串,通过(.)切分成三个为 Base64 编码的部分:

  • Header : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
  • Payload : 用来存放实际需要传递的数据
  • Signature(签名):服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

JWT 通常是这样的:xxxxx.yyyyy.zzzzz

Header 通常由两部分组成:

  • typ(Type):令牌类型,也就是 JWT。
  • alg(Algorithm):签名算法,比如 HS256。
{
  "alg": "HS256",
  "typ": "JWT"
}

2.2Payload

Payload 也是 JSON 格式数据,其中包含了 Claims(声明,包含 JWT 的相关信息)。

Claims 分为三种类型:

  • Registered Claims(注册声明):预定义的一些声明,建议使用,但不是强制性的。
  • Public Claims(公有声明):JWT 签发方可以自定义的声明,但是为了避免冲突,应该在 IANA JSON Web Token Registryopen in new window 中定义它们。
  • Private Claims(私有声明):JWT 签发方因为项目需要而自定义的声明,更符合实际项目场景使用。

下面是一些常见的注册声明:

  • iss(issuer):JWT 签发方。
  • iat(issued at time):JWT 签发时间。
  • sub(subject):JWT 主题。
  • aud(audience):JWT 接收方。
  • exp(expiration time):JWT 的过期时间。
  • nbf(not before time):JWT 生效时间,早于该定义的时间的 JWT 不能被接受处理。
  • jti(JWT ID):JWT 唯一标识。
{
  "uid": "ff1212f5-d8d1-4496-bf41-d2dda73de19a",
  "sub": "1234567890",
  "name": "John Doe",
  "exp": 15323232,
  "iat": 1516239022,
  "scope": ["admin", "user"]
}

Payload 部分默认是不加密的,一定不要将隐私信息存放在 Payload 当中!!!

2.3Signature

Signature 部分是对前两部分的签名,作用是防止 JWT(主要是 payload) 被篡改。

这个签名的生成需要用到:

  • Header + Payload。
  • 存放在服务端的密钥(一定不要泄露出去)。
  • 签名算法。
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,这个字符串就是 JWT 。


三、如何基于 JWT 进行身份验证?

步骤如下:

  1. 用户向服务器发送用户名、密码以及验证码用于登陆系统。
  2. 如果用户用户名、密码以及验证码校验正确的话,服务端会返回已经签名的 Token,也就是 JWT。
  3. 用户以后每次向后端发请求都在 Header 中带上这个 JWT 。
  4. 服务端检查 JWT 并从中获取用户相关信息。

两点建议:

  1. 建议将 JWT 存放在 localStorage 中,放在 Cookie 中会有 CSRF 风险。
  2. 请求服务端并携带 JWT 的常见做法是将其放在 HTTP Header 的 Authorization 字段中(Authorization: Bearer Token)。

四、如何防止 JWT 被篡改?

有了签名之后,即使 JWT 被泄露或者截获,黑客也没办法同时篡改 Signature、Header、Payload。

这是为什么呢?因为服务端拿到 JWT 之后,会解析出其中包含的 Header、Payload 以及 Signature 。服务端会根据 Header、Payload、密钥再次生成一个 Signature。拿新生成的 Signature 和 JWT 中的 Signature 作对比,如果一样就说明 Header 和 Payload 没有被修改。

不过,如果服务端的秘钥也被泄露的话,黑客就可以同时篡改 Signature、Header、Payload 了。黑客直接修改了 Header 和 Payload 之后,再重新生成一个 Signature 就可以了。

密钥一定保管好,一定不要泄露出去。JWT 安全的核心在于签名,签名安全的核心在密钥。


五、如何加强 JWT 的安全性?

  1. 使用安全系数高的加密算法。
  2. 使用成熟的开源库,没必要造轮子。
  3. JWT 存放在 localStorage 中而不是 Cookie 中,避免 CSRF 风险。
  4. 一定不要将隐私信息存放在 Payload 当中。
  5. 密钥一定保管好,一定不要泄露出去。JWT 安全的核心在于签名,签名安全的核心在密钥。
  6. Payload 要加入 exp (JWT 的过期时间),永久有效的 JWT 不合理。并且,JWT 的过期时间不易过长。

六、JWT 的优势

6.1无状态

JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。

不过,也正是由于 JWT 的无状态,也导致了它最大的缺点:不可控!

就比如说,我们想要在 JWT 有效期内废弃一个 JWT 或者更改它的权限的话,并不会立即生效,通常需要等到有效期过后才可以。再比如说,当用户 Logout 的话,JWT 也还有效。除非,我们在后端增加额外的处理逻辑比如将失效的 JWT 存储起来,后端先验证 JWT 是否有效再进行处理。具体的解决办法,我们会在后面的内容中详细介绍到,这里只是简单提一下。

6.2有效避免了 CSRF 攻击

CSRF(Cross Site Request Forgery) 一般被翻译为 跨站请求伪造,属于网络攻击领域范围。相比于 SQL 脚本注入、XSS 等安全攻击方式,CSRF 的知名度并没有它们高。但是,它的确是我们开发系统时必须要考虑的安全隐患。就连业内技术标杆 Google 的产品 Gmail 也曾在 2007 年的时候爆出过 CSRF 漏洞,这给 Gmail 的用户造成了很大的损失。

那么究竟什么是跨站请求伪造呢? 简单来说就是用你的身份去做一些不好的事情(发送一些对你不友好的请求比如恶意转账)。

CSRF 攻击需要依赖 Cookie ,Session 认证中 Cookie 中的 SessionID 是由浏览器发送到服务端的,只要发出请求,Cookie 就会被携带。借助这个特性,即使黑客无法获取你的 SessionID,只要让你误点攻击链接,就可以达到攻击效果。

另外,并不是必须点击链接才可以达到攻击效果,很多时候,只要你打开了某个页面,CSRF 攻击就会发生。

那为什么 JWT 不会存在这种问题呢?

一般情况下我们使用 JWT 的话,在我们登录成功获得 JWT 之后,一般会选择存放在 localStorage 中。前端的每一个请求后续都会附带上这个 JWT,整个过程压根不会涉及到 Cookie。因此,即使你点击了非法链接发送了请求到服务端,这个非法请求也是不会携带 JWT 的,所以这个请求将是非法的。

总结来说就一句话:使用 JWT 进行身份验证不需要依赖 Cookie ,因此可以避免 CSRF 攻击。

不过,这样也会存在 XSS 攻击的风险。为了避免 XSS 攻击,你可以选择将 JWT 存储在标记为httpOnly 的 Cookie 中。但是,这样又导致了你必须自己提供 CSRF 保护,因此,实际项目中我们通常也不会这么做。

常见的避免 XSS 攻击的方式是过滤掉请求中存在 XSS 攻击风险的可疑字符串。

在 Spring 项目中,我们一般是通过创建 XSS 过滤器来实现的。

6.3适合移动端应用

使用 Session 进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到 Cookie(需要 Cookie 保存 SessionId),所以不适合移动端。

但是,使用 JWT 进行身份认证就不会存在这种问题,因为只要 JWT 可以被客户端存储就能够使用,而且 JWT 还可以跨语言使用。

6.4单点登录友好

使用 Session 进行身份认证的话,实现单点登录,需要我们把用户的 Session 信息保存在一台电脑上,并且还会遇到常见的 Cookie 跨域的问题。但是,使用 JWT 进行认证的话, JWT 被保存在客户端,不会存在这些问题。


七、JWT 身份认证常见问题及解决办法

7.1注销登录等场景下 JWT 还有效

与之类似的具体相关场景有:

  • 退出登录;
  • 修改密码;
  • 服务端修改了某个用户具有的权限或者角色;
  • 用户的帐户被封禁/删除;
  • 用户被服务端强制注销;
  • 用户被踢下线;
  • ……

这个问题不存在于 Session 认证方式中,因为在 Session 认证方式中,遇到这种情况的话服务端删除对应的 Session 记录即可。但是,使用 JWT 认证的方式就不好解决了。我们也说过了,JWT 一旦派发出去,如果后端不增加其他逻辑的话,它在失效之前都是有效的。

那我们如何解决这个问题呢?查阅了很多资料,我简单总结了下面 4 种方案:

1、将 JWT 存入内存数据库

将 JWT 存入 DB 中,Redis 内存数据库在这里是不错的选择。如果需要让某个 JWT 失效就直接从 Redis 中删除这个 JWT 即可。但是,这样会导致每次使用 JWT 发送请求都要先从 DB 中查询 JWT 是否存在的步骤,而且违背了 JWT 的无状态原则。

2、黑名单机制

和上面的方式类似,使用内存数据库比如 Redis 维护一个黑名单,如果想让某个 JWT 失效的话就直接将这个 JWT 加入到 黑名单 即可。然后,每次使用 JWT 进行请求的话都会先判断这个 JWT 是否存在于黑名单中。

前两种方案的核心在于将有效的 JWT 存储起来或者将指定的 JWT 拉入黑名单。

虽然这两种方案都违背了 JWT 的无状态原则,但是一般实际项目中我们通常还是会使用这两种方案。

3、修改密钥 (Secret) :

我们为每个用户都创建一个专属密钥,如果我们想让某个 JWT 失效,我们直接修改对应用户的密钥即可。但是,这样相比于前两种引入内存数据库带来了危害更大:

  • 如果服务是分布式的,则每次发出新的 JWT 时都必须在多台机器同步密钥。为此,你需要将密钥存储在数据库或其他外部服务中,这样和 Session 认证就没太大区别了。
  • 如果用户同时在两个浏览器打开系统,或者在手机端也打开了系统,如果它从一个地方将账号退出,那么其他地方都要重新进行登录,这是不可取的。

4、保持令牌的有效期限短并经常轮换

很简单的一种方式。但是,会导致用户登录状态不会被持久记录,而且需要用户经常登录。

另外,对于修改密码后 JWT 还有效问题的解决还是比较容易的。说一种我觉得比较好的方式:使用用户的密码的哈希值对 JWT 进行签名。因此,如果密码更改,则任何先前的令牌将自动无法验证。


八、JWT 的续签问题

很简单的一种方式。但是,会导致用户登录状态不会被持久记录,而且需要用户经常登录。

另外,对于修改密码后 JWT 还有效问题的解决还是比较容易的。说一种我觉得比较好的方式:使用用户的密码的哈希值对 JWT 进行签名。因此,如果密码更改,则任何先前的令牌将自动无法验证。

JWT 的续签问题

JWT 有效期一般都建议设置的不太长,那么 JWT 过期后如何认证,如何实现动态刷新 JWT,避免用户经常需要重新登录?

我们先来看看在 Session 认证中一般的做法:假如 Session 的有效期 30 分钟,如果 30 分钟内用户有访问,就把 Session 有效期延长 30 分钟。

JWT 认证的话,我们应该如何解决续签问题呢?查阅了很多资料,我简单总结了下面 4 种方案:

1、类似于 Session 认证中的做法

这种方案满足于大部分场景。假设服务端给的 JWT 有效期设置为 30 分钟,服务端每次进行校验时,如果发现 JWT 的有效期马上快过期了,服务端就重新生成 JWT 给客户端。客户端每次请求都检查新旧 JWT,如果不一致,则更新本地的 JWT。这种做法的问题是仅仅在快过期的时候请求才会更新 JWT ,对客户端不是很友好。

2、每次请求都返回新 JWT

这种方案的的思路很简单,但是,开销会比较大,尤其是在服务端要存储维护 JWT 的情况下。

3、JWT 有效期设置到半夜

这种方案是一种折衷的方案,保证了大部分用户白天可以正常登录,适用于对安全性要求不高的系统。

4、用户登录返回两个 JWT

第一个是 accessJWT ,它的过期时间 JWT 本身的过期时间比如半个小时,另外一个是 refreshJWT 它的过期时间更长一点比如为 1 天。客户端登录后,将 accessJWT 和 refreshJWT 保存在本地,每次访问将 accessJWT 传给服务端。服务端校验 accessJWT 的有效性,如果过期的话,就将 refreshJWT 传给服务端。如果有效,服务端就生成新的 accessJWT 给客户端。否则,客户端就重新登录即可。

这种方案的不足是:

  • 需要客户端来配合;
  • 用户注销的时候需要同时保证两个 JWT 都无效;
  • 重新请求获取 JWT 的过程中会有短暂 JWT 不可用的情况(可以通过在客户端设置定时器,当 accessJWT 快过期的时候,提前去通过 refreshJWT 获取新的 accessJWT);
  • 存在安全问题,只要拿到了未过期的 refreshJWT 就一直可以获取到 accessJWT。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1246305.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

_STORAGE_WRITE_ERROR_ thinkphp报错问题原因

整个报错内容如下 Uncaught exception Think\Exception with message _STORAGE_WRITE_ERROR_:./Runtime/Cache/Home/1338db9dec777aab181d4e74d1bdf964.php in C:\inetpub\wwwroot\ThinkPHP\Common\functions.php:101 Stack trace: #0 C:\inetpub\wwwroot\ThinkPHP\Library\…

“圆柱-计算公式“技术支持网址

该软件可以计算圆柱的底面圆周长、底面积、侧面积和体积。 您在使用中有遇到任何问题都可以和我们联系。我们会在第一时间回复您。 邮箱地址:elmo30zeongmail.com 谢谢!

【深度学习】CNN中pooling层的作用

1、pooling是在卷积网络(CNN)中一般在卷积层(conv)之后使用的特征提取层,使用pooling技术将卷积层后得到的小邻域内的特征点整合得到新的特征。一方面防止无用参数增加时间复杂度,一方面增加了特征的整合度…

骨传导能保护听力吗?为什么说骨传导耳机可以保护听力?

由于骨传导耳机的特殊传声方式,是可以保护听力的。 首先了解下骨传导耳机的传声方式是什么: 骨传导耳机是通过骨骼震动传导技术,将声音传至颅骨,然后通过颅骨传导到内耳,直接刺激听觉神经,使人感知到声音…

最全的电商API接口|全面淘宝平台数据接口参数和文档说明

淘宝联盟“工具服务商”开放招募 为了支持生态淘宝客业务提效及新业务模式拓展,淘宝联盟针对各工具业务模式招募若干工具服务商团队,仅限符合该招募规则的开发者申请创建工具服务商AppKey,并针对新引入的工具服务商将开放对应模式所需要的“服…

易点易动固定资产管理系统:全生命周期管理的理想选择

在现代企业中,固定资产管理是一项至关重要的任务。为了确保企业的资产安全、提高资产利用率,全面管理固定资产的生命周期至关重要。易点易动固定资产管理系统为企业提供了一种全面的解决方案,实现了从固定资产申购、采购、入库、领用、退库、…

iOS强引用引起的内存泄漏

项目中遇到一个问题: 1.在A页面的ViewDidLoad 方法里写了一个接收通知的方法,如下图: 然后在B页面发送通知 (注:下图的NOTI 是 [NSNotificationCenter defaultCenter] 的宏, 考虑一下可能有小白看这篇文章…

打印菱形-第11届蓝桥杯选拔赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第9讲。 打印菱形&#xff…

Android笔记(十五):JetPack Compose的附带效应(二)-produceState和derivedStateOf

在本笔记中,将结合实例介绍produceState和derivedStateOf两个可组合函数。它们分别实现状态的转换。 (1)produceState将非Compose状态转换虫Compose状态 (2)derivedStateOf将多个状态转换成其他状态。 一、produceSta…

2023年金融信创行业研究报告

第一章 行业概况 1.1 定义 金融信创是指在金融行业中应用的信息技术,特别是那些涉及到金融IT基础设施、基础软件、应用软件和信息安全等方面的技术和产品。这一概念源于更广泛的“信创 (信息技术应用创新)”,即通过中国国产信息技术替换海外信息技术&a…

全球最大生产基地已投产,百年京西借智能悬架谋「新生」

受相关等爆款车型的高配置率及销量带动,空气悬架市场热度不减。 比如,理想在今年的理想魔毯空气悬架技术日上宣布,搭载空气悬架的车型累计交付已突破20万辆,在所有已交付的L9、L8、L7中,配备空气悬架的比例达93%。 作…

php通过curl方式发送接受xml数据

目录 1、php通过curl方式发送xml数据 2、php通过file_get_contents接受curl方式发送xml数据 1、php通过curl方式发送xml数据 <?php function sendXmlData($url, $xmlData) {$ch curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFE…

亚马逊云科技向量数据库助力生成式AI成功落地实践探秘(二)

向量数据库选择哪种近似搜索算法&#xff0c;选择合适的集群规模以及集群设置调优对于知识库的读写性能也十分关键&#xff0c;主要需要考虑以下几个方面&#xff1a; 向量数据库算法选择 在 OpenSearch 里&#xff0c;提供了两种 k-NN 的算法&#xff1a;HNSW (Hierarchical…

代码随想录算法训练营第四十四天【动态规划part06】 | 完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ

完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 题目链接&#xff1a; 题目页…

android keylayout键值适配

1、通过getevent打印查看当前keyevent数字对应事件和物理码 2、dumpsys input 查看输入事件对应的 KeyLayoutFile: /system/usr/keylayout/Vendor_6080_Product_8060.kl 3、通过物理码修改键值映射&#xff0c;修改/system/usr/keylayout/目录下的文件

嵌入式系统在工业自动化中的智能化和自适应控制

嵌入式系统在工业自动化中扮演着实现智能化和自适应控制的重要角色。通过集成先进的算法和人工智能技术&#xff0c;嵌入式系统能够实现对生产过程的智能监控、分析、决策和调整&#xff0c;以提高生产线的效率、质量和稳定性。下面将详细介绍嵌入式系统在工业自动化中智能化和…

​飞凌嵌入式FCU2601网关,为工商业储能EMS注入智慧的力量

一、火热的储能行业&#xff0c;寻求新的市场机会 最近一段时间以来&#xff0c;世界储能大会、上海储能展、能源电子产业发展大会等多个储能相关论坛和展览密集登场&#xff0c;即使“内卷”已成为了业内讨论的热词&#xff0c;但寻求新的市场机会仍然是行业共识&#xff0c;…

“强标”即将迎来正式发布,智能汽车准备好了吗?

汽车越来越智能&#xff0c;这让汽车安全在传统的功能安全之外又多了一项新的命题&#xff1a;信息安全。广州国际车展开幕前&#xff0c;有媒体发起了一项调研&#xff0c;调研结果显示43%的用户将“信息安全”和品牌、外观、价格、续航等一起纳入了购买智能汽车的首要考虑因素…

虚拟机系列:vmware和Oracle VM VirtualBox虚拟机的区别,简述哪一个更适合我?以及相互转换

一. VMware和Oracle VM VirtualBox虚拟机的区别主要体现在以下几个方面: 首先两种软件的安装使用教程如下: VMware ESXI 安装使用教程 Oracle VM VirtualBox安装使用教程 商业模式:VMware是一家商业公司,而Oracle VM VirtualBox是开源软件; 功能:VMware拥有更多的功能和…

工业以太网交换机未来发展中的几个趋势

随着工业自动化不断发展和智能制造的推进&#xff0c;工业以太网交换机在未来的应用中将面临更多的发展机遇和挑战。在工业以太网交换机的未来发展中&#xff0c;有几个方面将成为趋势。 网络虚拟化 随着工业自动化系统规模的不断扩展&#xff0c;网络虚拟化将成为未来的发展方…