JWT
什么是 JWT?
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用程序之间安全地传输信息。它被设计用于在两方之间传输声明,这些声明可以是身份验证和授权信息,也可以是任何其他类型的信息。
设计目的:不需要服务器端存储状态,安全地传递非敏感信息。
JWT 特点
- 可扩展性:可以在 payload 中携带任意的 JSON 数据
- 自包含性:所有用户相关信息都在 JWT 中,不需要依赖数据库
- 无状态性:服务器不需要保存会话状态,提高了系统的可扩展性
- 跨域支持:可以跨域传递,因为是 JSON 格式
- 安全性:通过签名确保数据不被篡改
JWT 组成
eyJraWQiOiJmYTNkZmZjMS0xZmQ3LTRhM2QtYTEyMC1mNjY4OWE4NDM5YjQiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJjbGllbnQiLCJhdWQiOiJjbGllbnQiLCJuYmYiOjE3MTc1NDk5NDMsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MCIsImV4cCI6MTcxNzU1MDI0MywiaWF0IjoxNzE3NTQ5OTQzLCJqdGkiOiJiMjU0ZGVhMi1kMWE2LTQxNzEtYjEyYy1lNmYzYzZjMDJkMGQifQ.eRiS0H2E-h5PiDEfJikjoPGH1DCqWVt4VIzLtPoSOaIK6jBIaw0h5m-reZVUyZPNYZG68Ymhey17aZBMveirqCxN-lNcPMIGfuqMptfsD9E6Hfam6bEMgpEAOQsQ6Ruk3vGtdmjnEC2h9ZStoqT5-C6JgArwFLGgX92LXrRYz7-60n0I6EAB07u9kxc6FQKLow90RiyXi2YLur-ttOUQpecf8zHi48zRc-HLLoWAMaNddT-4hg4v0Qts4DultpxZB_Xu7DRc91G_8M6sYFSvFSVFHlcWFgKNLZqUYwepLHX2LxoXdbTLGqV9x__-J8UO0TO3TkpC2BaZAiseYcpYMw
JWT 主要有以下三个部分通过 base64 加密组成:
Header(头部):描述 JWT 的元数据,通常包含两部分信息:
- 声明类型,通常是 “JWT”
- 所使用的哈希算法,如 HMAC SHA256 或 RSA
Payload(负载):包含声明,即一些跟当前用户相关的重要信息,如用户 ID、用户角色等。
Signature(签名):由 header 和 payload 使用密钥进行签名而组成,用于验证消息不被篡改。
HMAC_SHA256( secret, base64urlEncoding(header) + '.' + base64urlEncoding(payload) )
HMAC-SHA256 是一种基于加密哈希函数的消息认证码(HMAC)算法,是对称算法,它结合使用了 HMAC 和 SHA-256 哈希函数。
Header base64解密后:
{
"kid": "fa3dffc1-1fd7-4a3d-a120-f6689a8439b4",
"alg": "RS256"
}
Payload 解密后:
{
"sub": "client",
"aud": "client",
"nbf": 1717549943,
"iss": "http://localhost:8080",
"exp": 1717550243,
"iat": 1717549943,
"jti": "b254dea2-d1a6-4171-b12c-e6f3c6c02d0d"
}
JWS 和 JWE
JWS(JSON Web Signature)是 JSON Web Token (JWT) 规范的一个子规范,它定义了使用 JSON 数据结构表示签名或未签名的内容。
- 只对内容做签名,确保其不被篡改,但内容本身并没有加密。
JWS 主要包含以下三个部分:
- Header:描述签名或加密所使用的算法及其参数。通常包含两个字段:
alg
:签名或加密所使用的算法typ
:表示这是一个 JWS 对象
- Payload:要签名或加密的 JSON 数据。这通常就是 JWT 的负载部分。
- Signature:使用 Header 中指定的算法对 Header 和 Payload 进行签名的结果。签名的目的是验证数据的完整性和真实性。
JWS 有两种表示方式:
- Compact Serialization:
- 由点号(
.
)分隔的三个 Base64URL 编码的字符串组成 - 格式为:
header.payload.signature
- 由点号(
- JSON Serialization:
- 使用 JSON 对象表示 Header、Payload 和 Signature
- 格式为:
{"protected":"...","payload":"...","signature":"..."}
JWE(JSON Web Encryption)是 JSON Web Token (JWT) 规范的另一个子规范,它定义了使用 JSON 数据结构表示加密的内容。
- 会对内容本身加密,相对更安全,当然成本也会高一些。
JWE 主要包含以下五个部分:
- Header:描述加密所使用的算法及其参数。通常包含两个字段:
alg
:密钥加密算法enc
:内容加密算法
- Encrypted Key:使用 Header 中的
alg
指定的算法加密的密钥。这个密钥用于解密 Ciphertext。 - Initialization Vector (IV):用于内容加密的初始化向量。
- Ciphertext:使用 Header 中的
enc
指定的算法加密的原始数据。 - Authentication Tag:用于验证数据完整性和真实性的认证标签。
JWE 有两种表示方式:
- Compact Serialization:
- 由点号(
.
)分隔的五个 Base64URL 编码的字符串组成 - 格式为:
header.encrypted_key.iv.ciphertext.tag
- 由点号(
- JSON Serialization:
- 使用 JSON 对象表示上述五个部分
- 格式为:
{"protected":"...","encrypted_key":"...","iv":"...","ciphertext":"...","tag":"..."}
它们之间有以下几个主要区别:
- 目的不同:
- JWS 用于对 JWT 的内容进行数字签名,以确保数据的完整性和真实性。
- JWE 用于对 JWT 的内容进行加密,以确保数据的机密性。
- 处理方式不同:
- JWS 在消息的头部、负载和签名部分执行签名操作。
- JWE 在消息的头部、加密密钥、初始化向量、密文和认证标签部分执行加密操作。
- 安全保证不同:
- JWS 通过数字签名保证数据不被篡改。
- JWE 通过加密保证数据不被窃取。
- 算法选择不同:
- JWS 支持多种签名算法,如 HMAC、RSA、ECDSA 等。
- JWE 支持多种加密算法,如 RSA、ECDH-ES、AES 等。
- 应用场景不同:
- JWS 常用于身份验证和授权,如 OAuth2.0。
- JWE 常用于机密数据传输,如敏感信息、加密聊天等。
常见的 JWT 是 JWS 的实现,它的头部和载荷都是没有加密的,所以它的目的并不是想隐藏数据,它的目的是防止数据被篡改,这点是通过第三方签名来实现的
JWT 应用场景
- 身份验证和授权:
- 用于在客户端和服务器之间传递经过验证的身份信息。
- 通过服务器签发 JWT,客户端可以在随后的请求中使用该 JWT 进行身份验证。
- 在基于 OAuth 2.0 的授权流程中,JWT 可以作为访问令牌或刷新令牌使用。
- 无状态会话管理:
- 由于 JWT 包含了所有必要的信息,服务器可以无状态地验证和授权用户。
- 这样可以减轻服务器的负担,提高系统的可扩展性。
- 跨域资源共享 (CORS):
- 由于 JWT 是自包含的,可以在不同的域之间安全地传输用户信息。
- 这对于构建分布式应用程序很有用。
- API 认证:
- 客户端可以在每次 API 请求中携带 JWT,服务器验证 JWT 来确认客户端的身份。
- 这种方式比传统的 session/cookie 机制更加安全和可扩展。
- 单点登录 (SSO):
- 在单点登录系统中,JWT 可以用于在多个应用程序之间传递经过验证的用户身份信息。
- 这样用户只需要登录一次就可以访问所有的应用程序。
- 移动应用认证:
- 在移动应用程序中,JWT 可以作为无状态的身份验证机制,取代传统的 session/cookie 方式。
- 这样可以更好地适应移动端的特点,如设备电池寿命和网络条件的限制。
- IoT 设备认证:
- 在物联网场景中,JWT 可以用于在 IoT 设备和后端服务之间进行安全认证。
- 这种方式比传统的 API 密钥机制更加灵活和安全。
JWT 和其他其他认证方式比较
JWT | Cookie | API KEY | |
---|---|---|---|
是否有状态 | 有 | 无 | 无 |
应用场景 | 前后端、后端服务之间 | 前后端 | 一般后端服务之间 |
认证对象 | 主要针对用户 | 针对用户 | 主要针对系统、应用 |
可撤销 | 不方便 | 方便 | 方便 |
生成方式 | 认证过程中动态生成 | 认证过程中动态生成 | 预先分配 |
JWT 缺点
- 服务端没有真正退出登录
- 用户信息修改没法及时同步
- token 泄露无有效手段立即将 token 无效