Skip to content

Commit ac329b7

Browse files
committed
[docs update]完善对jwt的介绍
1 parent 91cfef6 commit ac329b7

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

docs/system-design/security/advantages-and-disadvantages-of-jwt.md

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@ tag:
55
- 安全
66
---
77

8-
[JWT 基本概念详解](https://javaguide.cn/system-design/security/jwt-intro.html)这篇文章中,我介绍了:
8+
校招面试中,遇到大部分的候选者认证登录这块用的都是 JWT。提问 JWT 的概念性问题以及使用 JWT 的原因,基本都能回答一些,但当问到 JWT 存在的一些问题和解决方案时,只有一小部分候选者回答的还可以。
99

10-
- 什么是 JWT?
11-
- JWT 由哪些部分组成?
12-
- 如何基于 JWT 进行身份验证?
13-
- JWT 如何防止 Token 被篡改?
14-
- 如何加强 JWT 的安全性?
10+
JWT 不是银弹,也有很多缺陷,很多时候并不是最优的选择。这篇文章,我们一起探讨一下 JWT 身份认证的优缺点以及常见问题的解决办法,来看看为什么很多人不再推荐使用 JWT 了。
1511

16-
这篇文章,我们一起探讨一下 JWT 身份认证的优缺点以及常见问题的解决办法
12+
关于 JWT 的基本概念介绍请看我写的这篇文章: [JWT 基本概念详解](https://javaguide.cn/system-design/security/jwt-intro.html)
1713

1814
## JWT 的优势
1915

@@ -170,15 +166,35 @@ JWT 认证的话,我们应该如何解决续签问题呢?查阅了很多资
170166
- 重新请求获取 JWT 的过程中会有短暂 JWT 不可用的情况(可以通过在客户端设置定时器,当 accessJWT 快过期的时候,提前去通过 refreshJWT 获取新的 accessJWT);
171167
- 存在安全问题,只要拿到了未过期的 refreshJWT 就一直可以获取到 accessJWT。不过,由于 refreshJWT 只用来获取 accessJWT,不容易被泄露。
172168

169+
### JWT 体积太大
170+
171+
JWT 结构复杂(Header、Payload 和 Signature),包含了更多额外的信息,还需要进行 Base64Url 编码,这会使得 JWT 体积较大,增加了网络传输的开销。
172+
173+
JWT 组成:
174+
175+
![JWT 组成](https://oss.javaguide.cn/javaguide/system-design/jwt/jwt-composition.png)
176+
177+
JWT 示例:
178+
179+
```plain
180+
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
181+
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
182+
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
183+
```
184+
185+
解决办法:
186+
187+
- 尽量减少 JWT Payload(载荷)中的信息,只保留必要的用户和权限信息。
188+
- 在传输 JWT 之前,使用压缩算法(如 GZIP)对 JWT 进行压缩以减少体积。
189+
- 在某些情况下,使用传统的 Token 可能更合适。传统的 Token 通常只是一个唯一标识符,对应的信息(例如用户 ID、Token 过期时间、权限信息)存储在服务端,通常会通过 Redis 保存。
190+
173191
## 总结
174192

175-
JWT 其中一个很重要的优势是无状态,但实际上,我们想要在实际项目中合理使用 JWT 的话,也还是需要保存 JWT 信息。
193+
JWT 其中一个很重要的优势是无状态,但实际上,我们想要在实际项目中合理使用 JWT 做认证登录的话,也还是需要保存 JWT 信息。
176194

177195
JWT 也不是银弹,也有很多缺陷,具体是选择 JWT 还是 Session 方案还是要看项目的具体需求。万万不可尬吹 JWT,而看不起其他身份认证方案。
178196

179-
另外,不用 JWT 直接使用普通的 Token(随机生成,不包含具体的信息) 结合 Redis 来做身份认证也是可以的。我在 [「优质开源项目推荐」](https://javaguide.cn/open-source-project/)的第 8 期推荐过的 [Sa-Token](https://github.com/dromara/sa-token) 这个项目是一个比较完善的 基于 JWT 的身份认证解决方案,支持自动续签、踢人下线、账号封禁、同端互斥登录等功能,感兴趣的朋友可以看看。
180-
181-
![](https://oss.javaguide.cn/javaguide/system-design/jwt/image-20220609170714725.png)
197+
另外,不用 JWT 直接使用普通的 Token(随机生成的 ID,不包含具体的信息) 结合 Redis 来做身份认证也是可以的。
182198

183199
## 参考
184200

docs/system-design/security/jwt-intro.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ JWT 自身包含了身份验证所需要的所有信息,因此,我们的服
2525
2626
## JWT 由哪些部分组成?
2727

28-
![此图片来源于:https://supertokens.com/blog/oauth-vs-jwt](https://oss.javaguide.cn/javaguide/system-design/jwt/jwt-composition.png)
28+
![JWT 组成](https://oss.javaguide.cn/javaguide/system-design/jwt/jwt-composition.png)
2929

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

32-
- **Header** : 描述 JWT 的元数据,定义了生成签名的算法以及 `Token` 的类型。
33-
- **Payload** : 用来存放实际需要传递的数据
34-
- **Signature(签名)**:服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。
32+
- **Header(头部)** : 描述 JWT 的元数据,定义了生成签名的算法以及 `Token` 的类型。Header 被 Base64Url 编码后成为 JWT 的第一部分
33+
- **Payload(载荷)** : 用来存放实际需要传递的数据,包含声明(Claims),如`sub`(subject,主题)、`jti`(JWT ID)。Payload 被 Base64Url 编码后成为 JWT 的第二部分。
34+
- **Signature(签名)**:服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。生成的签名会成为 JWT 的第三部分。
3535

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

0 commit comments

Comments
 (0)