doc: 阅读jwt文档

This commit is contained in:
asahi
2025-11-24 16:42:09 +08:00
parent f07db479b0
commit 8e1f2b72b4

View File

@@ -1,25 +1,159 @@
- [JWT](#jwt)
- [JWT应用场景](#jwt应用场景)
- [JSON Web Token结构](#json-web-token结构)
- [Header](#header)
- [Payload](#payload)
- [registered claims](#registered-claims)
- [Public claims](#public-claims)
- [private claims](#private-claims)
- [Signature](#signature)
- [putting together](#putting-together)
- [JSON Web Tokens工作方式](#json-web-tokens工作方式)
- [JWT的validation和verification](#jwt的validation和verification)
- [Validation](#validation)
- [Verification](#verification)
# JWT # JWT
* ## jwt简介 JSON Web Token是一个开源标准定义了一种`紧凑且自自包含`的方式用于在各方之间安全的传输信息这些信息以JSON对象的形式呈现。传输的信息是被数字签名的故而信息可以被验证并信任。
> jwt是一个开源标准。jwt定义了一个紧凑且自包含的方式安全的在多方之间通过json字符串传递信息。由于传递的信息会被签名故而信息是可验证和信任的。
jwt只能对payload中的信息进行验证并不会对信息进行加密。故而jwt中不应该包含敏感信息。jwt只是对header和payload的信息进行签名保证该信息的来源方式可信的。 JWT可以通过密钥使用hmac算法或public/private key pair使用RSA/ECDSA算法来进行签名
* ## jwt用途
* jwt通常用来进行认证操作 即使JWT可以通过加密在传递过程中提供安全性但是本文会集中在signed tokens
* jwt还可以用作信息交换由于传递的信息会被签名故而通过jwt来传输信息是安全的 - `signed tokens` signed tokens可以验证token中包含声明的完整性
* ## jwt结构 - `encrypted tokens` 加密则是将token中的claims内容向第三方隐藏
* ### Header
* 对于header部分的信息会进行base64url编码 ## JWT应用场景
* ### Payload 如下是JWT的常用场景
* 对于payload部分的数据也会进行base64url形式的编码 - Authorization这是JWT的最通用场景。一旦用户登录后续的请求都会包含JWT允许用户访问该JWT被允许的路由、服务、资源。
* - `单点登录`特性普遍使用JWT其带来开销较小并且能够轻松的跨domains使用
* ### Signature - Information ExchangeJWT能够安全的在各方传递信息。由于JWT可以被签名例如在使用public/private key时可以确保发送方身份的可靠性。
* 通常在header中记录了加密算法对base64url编码后的header和payload用指定算法和服务端私钥技能型签名后会生成签名部分 - 并且由于签名是通过header和payload进行计算的还可以用于验证token内容是否被修改
* 将签名部分和header、payload通过.分隔并且连接然后就可以生成jwt
* ## jwt认证流程 ## JSON Web Token结构
* 首先客户端第一次向服务端发送登录请求服务端根据客户端发送的用户名、密码等登录信息在数据库中查找信息并验证如果登录成功会在服务端生成一个jwt JWT的结构较为紧凑由三个部分组成三个部分之间通过`.`进行分隔:
* 服务端会将生成的jwt返回给客户端jwt中可以记录一些不敏感信息 - Header
* 而后每次客户端向服务端发送请求时都会携带jwt服务端在接收到jwt后会对jwt中的信息进行验证 - Payload
* ## jwt相对于session存储用户信息的优势 - Sinature
* jwt的数据存储在客户端中故而其并不会像session一样占用服务端内存能够有效减轻服务端的内存压力
* 将一些非敏感信息存储在jwt中可以避免服务端频繁的在数据库中查询信息 因此JWT通常看起来如下
* jwt是以json格式存储信息的故而jwt可以跨语言 ```
* jwt可以解决跨域问题不像cookie只能在同一父域名的不同子域名下共享 xxxxx.yyyyy.zzzzz
```
### Header
header通常由两部分组成
- token的类型JWT
- 使用的签名算法: HMAC/SHA256/RSA
示例如下所示:
```json
{
"alg": "HS256",
"typ": "JWT"
}
```
`对于JWT的第一部分而言json形式的内容会被以Base64Url的形式进行编码`
### Payload
token的第二部分是payload包含了token中的claims
- `claim`:即对某个实体及其附加数据的描述(实体通常是用户)
claims通常存在三种类型
- registered
- public
- private
#### registered claims
存在一系列预定义的claims并非强制但是推荐进行使用。
- `iss`: issuer签发者
- `exp`: expiration time过期时间
- `sub`subject主体例如用户唯一标识
- `aud`audience接收方/受众指JWT的目标接收方限制token的使用范围
#### Public claims
pubic claims可以被jwt的使用者任意定义。但是为了避免冲突public claims应该在`IANA JSON Web Token Registry`中被定义或在命名中包含namespace从而避免冲突。
#### private claims
private claims也可以被自由定义用于在各方之间共享信息。
private claims和public claims的区别如下
- private claims可以被任意定义只需要传递的双方协商一致即可
- public claims的命名需要遵守相应规范应在`IANA JSON Web Token Registry`中或以URI的形式定义
payload的示例如下所示
```json
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
```
作为JWT的第二部分上述内容也会通过Base64Url的形式进行编码。
### Signature
为了创建jwt的第三部分必须接收如下内容
- encoded header
- encoded payload
- secret
- header中指定的算法
可以根据上述内容生成签名。
例如,如果使用`HMAC SHA256`算法进行签名,签名应当以如下方式进行创建:
```
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
```
> HMACSHA256是一种基于hash的消息认证码算法需要提供secret和待散列的消息
signature会被用于验证token内容是否被修改并且在使用private key进行签名时可以验证jwt的签发方身份。
### putting together
最终的jwt会将上述三个部分通过`.`分隔符拼接在一起。
## JSON Web Tokens工作方式
在认证过程中当用户通过凭据成功登录后系统将会返回一个jwt。返回的token本身就是凭据需谨慎对待避免出现安全问题。
通常不应该在jwt中存储敏感的会话数据。
不论何时当用户想要访问受保护的route和resource时user agent都应该发送JWT。通常JWT被包含在`Authorization` header中并使用`Bearer` schema。header的内容如下所示
```
Authorization: Bearer <token>
```
在http header中发送jwt时必须避免jwt大小过大。部分server不接受超过8KB的headers。如果需要在jwt中集成较多信息需要使用替代方案例如`Auth0 Fine-Grained Authorization`
下图展示了JWT获取和通过JWT访问API、资源的流程
<img alt="How does a JSON Web Token work" loading="lazy" width="480" height="480" decoding="async" data-nimg="1" class="markdown-image_image__vmfuh" sizes="100vw" src="https://www.jwt.io//_next/image?url=https%3A%2F%2Fcdn.auth0.com%2Fwebsite%2Fjwt%2Fintroduction%2Fclient-credentials-grant.png&w=3840&q=75" style="color:transparent;width:100%;height:auto">
1. 应用或client会向authorization server请求授权
2. 当授权被授予后authorization server将会向应用返回access token
3. 应用将会使用token去访问受保护资源
需要注意在使用signed tokens时token中的所有内容都会暴露给用户和其他方即使他们无法修改这些信息。即不应该在token中包含机密信息。
## JWT的validation和verification
jwt的validation和verification针对的是JWT的不同方面
- validationjwt的格式是否正确
- verification确保jwt真实且未修改
### Validation
JWT validation会检查jwt的结构、格式、内容
- 结构确保jwt是被`.`符号分隔的三个部分header, payload, signature
- format校验每个部分都是使用Base64URL进行编码的的并且payload包含预期的claims
- content校验payload中的claims是否正确例如过期时间exp、issued_atiat、not beforenbf确保token没有过期并且没有在生效前使用
### Verification
verification保证的是jwt的真实性和完整性
- Signature Verification其为验证的主要环节会通过jwt的header和payload部分来校验jwt的signature部分。该部分会通过header中指定的算法例如RSA/ECDSA/HMAC来完成。如果签名不符合预期token可能被修改或来源非可信源。
- Issuer Verification校验`iss` claim指定的内容是否和预期相符
- Audience Check确保`aud` claim和预期相符