mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
[docs update]完善对jwt的介绍
This commit is contained in:
parent
91cfef68ec
commit
ac329b7b30
@ -5,15 +5,11 @@ tag:
|
|||||||
- 安全
|
- 安全
|
||||||
---
|
---
|
||||||
|
|
||||||
在 [JWT 基本概念详解](https://javaguide.cn/system-design/security/jwt-intro.html)这篇文章中,我介绍了:
|
校招面试中,遇到大部分的候选者认证登录这块用的都是 JWT。提问 JWT 的概念性问题以及使用 JWT 的原因,基本都能回答一些,但当问到 JWT 存在的一些问题和解决方案时,只有一小部分候选者回答的还可以。
|
||||||
|
|
||||||
- 什么是 JWT?
|
JWT 不是银弹,也有很多缺陷,很多时候并不是最优的选择。这篇文章,我们一起探讨一下 JWT 身份认证的优缺点以及常见问题的解决办法,来看看为什么很多人不再推荐使用 JWT 了。
|
||||||
- JWT 由哪些部分组成?
|
|
||||||
- 如何基于 JWT 进行身份验证?
|
|
||||||
- JWT 如何防止 Token 被篡改?
|
|
||||||
- 如何加强 JWT 的安全性?
|
|
||||||
|
|
||||||
这篇文章,我们一起探讨一下 JWT 身份认证的优缺点以及常见问题的解决办法。
|
关于 JWT 的基本概念介绍请看我写的这篇文章: [JWT 基本概念详解](https://javaguide.cn/system-design/security/jwt-intro.html)。
|
||||||
|
|
||||||
## JWT 的优势
|
## JWT 的优势
|
||||||
|
|
||||||
@ -170,15 +166,35 @@ JWT 认证的话,我们应该如何解决续签问题呢?查阅了很多资
|
|||||||
- 重新请求获取 JWT 的过程中会有短暂 JWT 不可用的情况(可以通过在客户端设置定时器,当 accessJWT 快过期的时候,提前去通过 refreshJWT 获取新的 accessJWT);
|
- 重新请求获取 JWT 的过程中会有短暂 JWT 不可用的情况(可以通过在客户端设置定时器,当 accessJWT 快过期的时候,提前去通过 refreshJWT 获取新的 accessJWT);
|
||||||
- 存在安全问题,只要拿到了未过期的 refreshJWT 就一直可以获取到 accessJWT。不过,由于 refreshJWT 只用来获取 accessJWT,不容易被泄露。
|
- 存在安全问题,只要拿到了未过期的 refreshJWT 就一直可以获取到 accessJWT。不过,由于 refreshJWT 只用来获取 accessJWT,不容易被泄露。
|
||||||
|
|
||||||
|
### JWT 体积太大
|
||||||
|
|
||||||
|
JWT 结构复杂(Header、Payload 和 Signature),包含了更多额外的信息,还需要进行 Base64Url 编码,这会使得 JWT 体积较大,增加了网络传输的开销。
|
||||||
|
|
||||||
|
JWT 组成:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
JWT 示例:
|
||||||
|
|
||||||
|
```plain
|
||||||
|
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
|
||||||
|
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
|
||||||
|
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
|
```
|
||||||
|
|
||||||
|
解决办法:
|
||||||
|
|
||||||
|
- 尽量减少 JWT Payload(载荷)中的信息,只保留必要的用户和权限信息。
|
||||||
|
- 在传输 JWT 之前,使用压缩算法(如 GZIP)对 JWT 进行压缩以减少体积。
|
||||||
|
- 在某些情况下,使用传统的 Token 可能更合适。传统的 Token 通常只是一个唯一标识符,对应的信息(例如用户 ID、Token 过期时间、权限信息)存储在服务端,通常会通过 Redis 保存。
|
||||||
|
|
||||||
## 总结
|
## 总结
|
||||||
|
|
||||||
JWT 其中一个很重要的优势是无状态,但实际上,我们想要在实际项目中合理使用 JWT 的话,也还是需要保存 JWT 信息。
|
JWT 其中一个很重要的优势是无状态,但实际上,我们想要在实际项目中合理使用 JWT 做认证登录的话,也还是需要保存 JWT 信息。
|
||||||
|
|
||||||
JWT 也不是银弹,也有很多缺陷,具体是选择 JWT 还是 Session 方案还是要看项目的具体需求。万万不可尬吹 JWT,而看不起其他身份认证方案。
|
JWT 也不是银弹,也有很多缺陷,具体是选择 JWT 还是 Session 方案还是要看项目的具体需求。万万不可尬吹 JWT,而看不起其他身份认证方案。
|
||||||
|
|
||||||
另外,不用 JWT 直接使用普通的 Token(随机生成,不包含具体的信息) 结合 Redis 来做身份认证也是可以的。我在 [「优质开源项目推荐」](https://javaguide.cn/open-source-project/)的第 8 期推荐过的 [Sa-Token](https://github.com/dromara/sa-token) 这个项目是一个比较完善的 基于 JWT 的身份认证解决方案,支持自动续签、踢人下线、账号封禁、同端互斥登录等功能,感兴趣的朋友可以看看。
|
另外,不用 JWT 直接使用普通的 Token(随机生成的 ID,不包含具体的信息) 结合 Redis 来做身份认证也是可以的。
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@ JWT 自身包含了身份验证所需要的所有信息,因此,我们的服
|
|||||||
|
|
||||||
## JWT 由哪些部分组成?
|
## JWT 由哪些部分组成?
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
JWT 本质上就是一组字串,通过(`.`)切分成三个为 Base64 编码的部分:
|
JWT 本质上就是一组字串,通过(`.`)切分成三个为 Base64 编码的部分:
|
||||||
|
|
||||||
- **Header** : 描述 JWT 的元数据,定义了生成签名的算法以及 `Token` 的类型。
|
- **Header(头部)** : 描述 JWT 的元数据,定义了生成签名的算法以及 `Token` 的类型。Header 被 Base64Url 编码后成为 JWT 的第一部分。
|
||||||
- **Payload** : 用来存放实际需要传递的数据
|
- **Payload(载荷)** : 用来存放实际需要传递的数据,包含声明(Claims),如`sub`(subject,主题)、`jti`(JWT ID)。Payload 被 Base64Url 编码后成为 JWT 的第二部分。
|
||||||
- **Signature(签名)**:服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。
|
- **Signature(签名)**:服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。生成的签名会成为 JWT 的第三部分。
|
||||||
|
|
||||||
JWT 通常是这样的:`xxxxx.yyyyy.zzzzz`。
|
JWT 通常是这样的:`xxxxx.yyyyy.zzzzz`。
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user