更多Python学习内容:ipengtao.com
随着现代Web应用的快速发展,安全性和用户认证成为了开发中的核心问题之一。JSON Web Token(JWT)作为一种轻量级的认证机制,广泛应用于API认证、分布式系统中的信息传递以及单点登录(SSO)等场景。JWT 的核心优势在于其轻量、跨平台以及能够将认证信息安全地嵌入到token中。PyJWT
是一个实现了JWT生成和验证的Python库,简单易用且功能全面。
安装
在开始使用 pyjwt
之前,需要安装该库。
可以通过以下命令安装:
pip install pyjwt
安装完成后,可以通过以下命令验证是否安装成功:
import jwt
print(jwt.__version__)
如果能够打印版本号,则说明安装成功。
主要功能
生成JWT:支持自定义payload(有效载荷)和头部信息。
签名和验证:支持多种签名算法(如HS256、RS256)。
Token过期控制:内置对
exp
(过期时间)、iat
(签发时间)和nbf
(生效时间)的支持。扩展功能:支持解码时的自定义验证。
这些功能使得 PyJWT
成为Python开发中实现JWT认证的理想选择。
基础用法
生成JWT
以下示例展示了如何使用 PyJWT
生成一个简单的JWT:
import jwt
# 定义密钥和payload
secret_key = "your_secret_key"
payload = {
"user_id": 123,
"username": "example_user"
}
# 生成JWT
token = jwt.encode(payload, secret_key, algorithm="HS256")
print(f"生成的JWT: {token}")
运行上述代码后会生成一个JWT字符串,该字符串可以作为API的认证凭据。
解码JWT
生成的JWT可以通过以下代码进行解码,以提取其中的有效载荷:
decoded_payload = jwt.decode(token, secret_key, algorithms=["HS256"])
print(f"解码后的内容: {decoded_payload}")
解码后的内容是一个字典,包含生成JWT时定义的所有信息。
添加Token过期时间
为了增强安全性,可以在JWT中添加过期时间(exp
)字段:
import jwt
import datetime
# 定义带有过期时间的payload
payload = {
"user_id": 123,
"username": "example_user",
"exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=60) # 1分钟后过期
}
token = jwt.encode(payload, secret_key, algorithm="HS256")
print(f"带有过期时间的JWT: {token}")
解码时,PyJWT
会自动验证Token是否过期:
try:
decoded_payload = jwt.decode(token, secret_key, algorithms=["HS256"])
print(f"有效载荷: {decoded_payload}")
except jwt.ExpiredSignatureError:
print("Token已过期")
验证Token的生效时间
JWT还支持 nbf
(Not Before)字段,用于控制Token的生效时间:
payload = {
"user_id": 123,
"username": "example_user",
"nbf": datetime.datetime.utcnow() + datetime.timedelta(seconds=10) # 10秒后生效
}
token = jwt.encode(payload, secret_key, algorithm="HS256")
print(f"带有生效时间的JWT: {token}")
try:
decoded_payload = jwt.decode(token, secret_key, algorithms=["HS256"])
print(f"有效载荷: {decoded_payload}")
except jwt.exceptions.ImmatureSignatureError:
print("Token尚未生效")
高级用法
使用RS256非对称加密
在分布式系统中,使用非对称加密算法(如RS256)可以提高安全性:
from jwt import encode, decode
# 加载公钥和私钥
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 = {"user_id": 123, "username": "example_user"}
token = encode(payload, private_key, algorithm="RS256")
# 使用公钥验证
decoded_payload = decode(token, public_key, algorithms=["RS256"])
print(f"解码后的内容: {decoded_payload}")
自定义验证逻辑
可以在解码JWT时添加额外的验证逻辑,例如检查特定字段:
def custom_verification(decoded_payload):
if "user_id" not in decoded_payload:
raise ValueError("缺少user_id字段")
token = jwt.encode({"user_id": 123}, secret_key, algorithm="HS256")
decoded_payload = jwt.decode(token, secret_key, algorithms=["HS256"], options={"verify_exp": False})
custom_verification(decoded_payload)
print("自定义验证通过")
黑名单功能
在实际应用中,为了实现Token失效功能,可以维护一个黑名单:
blacklist = set()
# 添加到黑名单
blacklist.add("expired_token")
# 验证Token
token = "expired_token"
if token in blacklist:
print("Token已失效")
else:
print("Token有效")
实际应用
用户认证系统
以下是一个实现基于JWT的简单用户认证系统的示例:
from flask import Flask, request, jsonify
import jwt
import datetime
app = Flask(__name__)
secret_key = "your_secret_key"
@app.route("/login", methods=["POST"])
def login():
username = request.json.get("username")
if username:
token = jwt.encode(
{"username": username, "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)},
secret_key,
algorithm="HS256"
)
return jsonify({"token": token})
return jsonify({"error": "用户名不能为空"}), 400
@app.route("/protected", methods=["GET"])
def protected():
token = request.headers.get("Authorization").split()[1]
try:
decoded_payload = jwt.decode(token, secret_key, algorithms=["HS256"])
return jsonify({"message": f"欢迎, {decoded_payload['username']}!"})
except jwt.ExpiredSignatureError:
return jsonify({"error": "Token已过期"}), 401
except jwt.InvalidTokenError:
return jsonify({"error": "无效的Token"}), 401
if __name__ == "__main__":
app.run(debug=True)
单点登录(SSO)
在单点登录场景中,JWT可以用来安全传递用户身份信息:
# 生成SSO Token
sso_payload = {"user_id": 456, "roles": ["admin"]}
sso_token = jwt.encode(sso_payload, secret_key, algorithm="HS256")
# 在其他服务验证SSO Token
decoded_sso_payload = jwt.decode(sso_token, secret_key, algorithms=["HS256"])
print(f"SSO用户信息: {decoded_sso_payload}")
总结
PyJWT
是一个功能强大的库,为开发者提供了实现JWT认证的便捷工具。它支持多种签名算法,提供了Token过期、签发和生效时间的控制,以及灵活的自定义验证功能。无论是实现简单的用户认证,还是构建复杂的分布式系统,PyJWT
都能显著提升开发效率和安全性。
如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!
我们还为大家准备了Python资料,感兴趣的小伙伴快来找我领取一起交流学习哦!
往期推荐
Beautiful Soup快速上手指南,从入门到精通(PDF下载)
80个Python数据分析必备实战案例.pdf(附代码),完全开放下载
全网最全 Pandas的入门与高级教程全集,都在这里了!(PDF下载)
点击下方“阅读原文”查看更多