Jose
python-jose
是一个用于在 Python 中处理 JSON Web Tokens (JWT)、JSON Web Signatures (JWS) 和 JSON Web Encryption (JWE) 的库,基于 JOSE (JSON Object Signing and Encryption) 标准。它通常用于对信息进行签名、加密,特别是在 OAuth2、OpenID Connect 和 API 认证中,广泛应用于用户身份验证和授权流程中。
以下是 python-jose
的详解教程,介绍如何生成、验证 JWT 以及常见的应用场景。
1. 安装 python-jose
首先需要安装 python-jose
,可以通过 pip
来安装:
pip install python-jose
2. 基本概念
- JWT (JSON Web Token): 一种开放的标准 (RFC 7519),定义了一种用于安全传输信息的紧凑、自包含的方式,通常用于认证和信息交换。
- JWS (JSON Web Signature): 是 JWT 的一种使用形式,通过对 JWT 进行签名确保信息未被篡改。
- JWE (JSON Web Encryption): 是 JWT 的另一种形式,用于对 JWT 进行加密,从而确保信息的机密性。
3. 使用 JWT 的基本流程
JWT 由三部分组成:头部 (header)、载荷 (payload) 和签名 (signature),它们被 .
分隔。下面是如何使用 python-jose
来生成和验证 JWT。
3.1 生成 JWT
python-jose
支持生成加密和签名的 JWT。在这里我们使用签名的 JWT (JWS) 作为示例。生成 JWT 的基本步骤如下:
from jose import jwt
# 定义密钥和算法
secret_key = 'mysecretkey'
algorithm = 'HS256'
# 定义 payload(有效载荷)
payload = {
'sub': '1234567890',
'name': 'John Doe',
'admin': True
}
# 生成 JWT
token = jwt.encode(payload, secret_key, algorithm=algorithm)
print(f"Generated Token: {token}")
这里我们使用 HS256
签名算法和一个密钥 (secret_key
) 来生成 JWT。生成的 token 可以用于客户端的认证请求中。
3.2 验证 JWT
一旦你有了 JWT,接下来就是验证它的真实性。这通常发生在服务器端,确保客户端发送的 JWT 未被篡改。
# 验证并解码 JWT
decoded_payload = jwt.decode(token, secret_key, algorithms=[algorithm])
print(f"Decoded Payload: {decoded_payload}")
jwt.decode()
函数会验证 JWT 的签名,如果签名有效,则返回原始的 payload
。如果签名无效或密钥不匹配,它将抛出异常。
4. 过期时间和其他标准声明
JWT 可以包含一些标准声明(claims),例如 exp
(过期时间)、iat
(签发时间)、sub
(主题)等。你可以在 payload
中添加这些声明来控制 JWT 的有效期。
4.1 设置过期时间
import datetime
from jose import jwt
# 定义密钥和算法
secret_key = 'mysecretkey'
algorithm = 'HS256'
# 设置过期时间(10分钟后过期)
expiration = datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
# 定义 payload,并加入 exp 声明
payload = {
'sub': '1234567890',
'name': 'John Doe',
'exp': expiration
}
# 生成 JWT
token = jwt.encode(payload, secret_key, algorithm=algorithm)
print(f"Generated Token with Expiration: {token}")
# 解码并验证 JWT
try:
decoded_payload = jwt.decode(token, secret_key, algorithms=[algorithm])
print(f"Decoded Payload: {decoded_payload}")
except jwt.ExpiredSignatureError:
print("Token has expired")
通过添加 exp
字段,我们可以为 JWT 设置一个过期时间。过期后,jwt.decode()
将会抛出 ExpiredSignatureError
异常。
4.2 其他声明
你还可以添加其他声明,如 iss
(发行者)、aud
(接收者)等。例如:
payload = {
'sub': '1234567890',
'name': 'John Doe',
'iss': 'mycompany',
'aud': 'myaudience',
'exp': expiration
}
在解码时,使用 jwt.decode()
函数可以验证 iss
和 aud
,确保 JWT 是由正确的发行者发出并被正确的接收者使用。
# 验证 JWT,包括发行者和接收者
decoded_payload = jwt.decode(token, secret_key, algorithms=[algorithm], issuer='mycompany', audience='myaudience')
5. 使用非对称加密 (RSA)
除了 HMAC 算法 (HS256),python-jose
还支持 RSA 算法 (RS256)。在使用 RSA 时,需要生成一对公钥和私钥,私钥用于签名,公钥用于验证。
5.1 生成 RSA 密钥对
你可以使用 OpenSSL 或其他工具生成 RSA 公钥和私钥对。
# 生成私钥
openssl genrsa -out private_key.pem 2048
# 生成公钥
openssl rsa -in private_key.pem -outform PEM -pubout -out public_key.pem
5.2 使用 RSA 签名和验证
使用 RSA 时,签名和验证的过程与 HMAC 类似。
from jose import jwt
# 加载私钥和公钥
with open('private_key.pem', 'r') as f:
private_key = f.read()
with open('public_key.pem', 'r') as f:
public_key = f.read()
# 定义 payload
payload = {
'sub': '1234567890',
'name': 'John Doe'
}
# 使用私钥生成 JWT
token = jwt.encode(payload, private_key, algorithm='RS256')
print(f"Generated Token: {token}")
# 使用公钥验证 JWT
decoded_payload = jwt.decode(token, public_key, algorithms=['RS256'])
print(f"Decoded Payload: {decoded_payload}")
6. 常见应用场景
6.1 用户认证
JWT 常用于用户认证。用户登录时,服务器生成一个 JWT 并发送给客户端,客户端随后将 JWT 包含在请求头中发给服务器,服务器验证 JWT 以确认用户身份。
6.2 API 授权
在 API 访问时,JWT 可用于授权。客户端使用 JWT 访问受保护的资源,服务器通过验证 JWT 确定请求是否有权限。
7. 总结
python-jose
是一个功能强大的库,适用于生成和验证 JWT。通过本文的教程,你学会了如何生成、验证 JWT,并且了解了如何使用对称和非对称加密算法来处理 JWT。你可以根据自己的需求选择合适的算法和声明,来确保认证和授权过程中的安全性。