PyJWT 是一个用 Python 实现的轻量级库,用于处理 JSON Web Token (JWT)。JWT 是一种安全的方式,用来表示双方之间经过签名的令牌,通常用于认证和授权场景。PyJWT 简化了 JWT 的生成和验证过程,使得开发者能够轻松地在 Python 项目中集成 JWT 功能。
在这篇博客中,我们将深入介绍 PyJWT,展示如何生成、解码和验证 JWT 令牌,并且会通过代码示例演示如何在实际项目中使用 PyJWT 进行认证和授权。
➰缘起
- 💯 什么是 JWT?
- 为什么选择 PyJWT?
- 💯 安装 PyJWT
- 💯 PyJWT 的基本用法
- 1. 生成 JWT 令牌
- 2. 解码 JWT 令牌
- 3. 验证 JWT 令牌
- 💯 PyJWT 支持的签名算法
- 1. 使用 RS256 生成 JWT 令牌
- 2. 使用公钥验证 JWT 令牌
- 💯 PyJWT 在 Web 应用中的实际应用
- 1. 使用 PyJWT 进行用户认证
- 💯 常见配置和选项汇总表
- 📥 下载地址
- 💬 结语
- 📒 参考文献
💯 什么是 JWT?
JWT 是一种将认证信息或用户信息以 JSON 格式进行编码并加密的令牌。JWT 令牌通常由三部分组成:
- Header(头部):声明令牌的类型和签名算法。
- Payload(负载):存储用户信息或其他数据。
- Signature(签名):对前两部分进行签名,以确保数据的完整性和安全性。
一个典型的 JWT 结构如下:
Header.Payload.Signature
为什么选择 PyJWT?
- 轻量且易于使用:PyJWT 非常简洁,提供了简单的接口来生成和验证 JWT。
- 支持多种算法:PyJWT 支持多种签名算法,包括 HMAC 和 RSA,使得开发者可以根据需求选择合适的加密方式。
- 集成简单:无论是 Web 项目还是 API 服务,PyJWT 都可以轻松与 Python 的 Flask、Django 等框架集成。
💯 安装 PyJWT
要在项目中使用 PyJWT,可以通过 pip
进行安装:
pip install pyjwt
安装完成后,即可在你的 Python 项目中使用 PyJWT 进行令牌的生成和验证。
💯 PyJWT 的基本用法
1. 生成 JWT 令牌
使用 PyJWT,生成 JWT 令牌非常简单。你只需要定义一个 payload
(即令牌中包含的信息),然后使用 jwt.encode()
方法对其进行签名。
import jwt
import datetime# 定义一个 payload
payload = {"user_id": 123,"username": "test_user","exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30) # 令牌有效期为 30 分钟
}# 使用密钥进行签名
secret = 'my_secret_key'# 生成 JWT
token = jwt.encode(payload, secret, algorithm='HS256')print(f"生成的 JWT 令牌:{token}")
在这个示例中,我们定义了一个包含用户 ID 和用户名的 payload
,并且设置了令牌的过期时间为 30 分钟。jwt.encode()
会使用 HMAC-SHA256 算法对 payload
进行签名,生成最终的 JWT 令牌。
2. 解码 JWT 令牌
一旦生成了 JWT 令牌,在验证时我们可以使用 jwt.decode()
方法来解码令牌,并提取其中的 payload
数据。
# 解码 JWT
decoded_payload = jwt.decode(token, secret, algorithms=['HS256'])print(f"解码后的 payload:{decoded_payload}")
通过解码,我们可以获得令牌中存储的用户信息或其他数据。
3. 验证 JWT 令牌
JWT 令牌通常用于认证系统中,因此在解码时,我们需要确保令牌的签名和内容是有效的。如果签名不匹配,或令牌已过期,解码将失败并抛出异常。
try:# 验证并解码 JWTdecoded_payload = jwt.decode(token, secret, algorithms=['HS256'])print(f"有效的令牌,payload:{decoded_payload}")
except jwt.ExpiredSignatureError:print("令牌已过期")
except jwt.InvalidTokenError:print("无效的令牌")
在这个示例中,我们使用 try-except
块来处理令牌的有效性。如果令牌已过期或签名无效,PyJWT 会抛出相应的异常。
💯 PyJWT 支持的签名算法
PyJWT 支持多种签名算法,常见的有:
- HS256:基于 HMAC 和 SHA256 的对称加密算法。
- RS256:基于 RSA 的非对称加密算法。
以下是使用 RSA 私钥和公钥进行签名和验证的示例:
1. 使用 RS256 生成 JWT 令牌
# 加载私钥
with open('private.pem', 'r') as f:private_key = f.read()# 生成 JWT
token = jwt.encode(payload, private_key, algorithm='RS256')
2. 使用公钥验证 JWT 令牌
# 加载公钥
with open('public.pem', 'r') as f:public_key = f.read()try:# 使用公钥验证令牌decoded_payload = jwt.decode(token, public_key, algorithms=['RS256'])print(f"有效的令牌,payload:{decoded_payload}")
except jwt.InvalidTokenError:print("无效的令牌")
💯 PyJWT 在 Web 应用中的实际应用
PyJWT 非常适合用于 Web 应用中的身份认证和授权。以下是如何在 Flask 中使用 PyJWT 来保护 API 接口的示例。
1. 使用 PyJWT 进行用户认证
from flask import Flask, request, jsonify
import jwt
import datetimeapp = Flask(__name__)
secret = 'my_secret_key'# 用户登录接口
@app.route('/login', methods=['POST'])
def login():username = request.json.get('username')password = request.json.get('password')# 假设验证用户名和密码成功if username == 'test_user' and password == 'password123':payload = {"user_id": 123,"username": username,"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30)}token = jwt.encode(payload, secret, algorithm='HS256')return jsonify({"token": token})else:return jsonify({"message": "Invalid credentials"}), 401# 受保护的 API 接口
@app.route('/protected', methods=['GET'])
def protected():token = request.headers.get('Authorization').split()[1]try:decoded_payload = jwt.decode(token, secret, algorithms=['HS256'])return jsonify({"message": f"Hello, {decoded_payload['username']}!"})except jwt.ExpiredSignatureError:return jsonify({"message": "Token has expired"}), 401except jwt.InvalidTokenError:return jsonify({"message": "Invalid token"}), 401if __name__ == '__main__':app.run(debug=True)
在这个示例中,我们创建了两个接口:
/login
:用户登录接口,成功登录后返回一个 JWT 令牌。/protected
:受保护的接口,只有在提供有效 JWT 令牌时才能访问。
💯 常见配置和选项汇总表
选项 | 功能描述 | 示例 |
---|---|---|
algorithms | 指定签名算法 | algorithms=['HS256'] |
jwt.encode() | 生成 JWT 令牌 | jwt.encode(payload, secret, algorithm='HS256') |
jwt.decode() | 解码并验证 JWT 令牌 | jwt.decode(token, secret, algorithms=['HS256']) |
jwt.ExpiredSignatureError | 捕获令牌过期异常 | except jwt.ExpiredSignatureError |
jwt.InvalidTokenError | 捕获无效令牌异常 | except jwt.InvalidTokenError |
📥 下载地址
PyJWT 最新版 下载地址
💬 结语
PyJWT 是一个非常轻量级且功能强大的库,它为 Python 开发者提供了便捷的 JWT 生成和验证功能。通过本文的示例,你可以快速上手使用 PyJWT 并将其集成到你的认证系统中。无论是基于对称加密的 HMAC,还是基于非对称加密的 RSA,PyJWT 都能轻松应对。同时,PyJWT 的简单接口和易于扩展的特性,使得它成为 Web 应用中实现认证和授权的理想工具。
📒 参考文献
- PyJWT 官方文档
- PyJWT GitHub仓库