- 💖 作者简介:大家好,我是Zeeland,全栈领域优质创作者。
- 📝 CSDN主页:Zeeland🔥
- 📣 我的博客:Zeeland
- 📚 Github主页: Undertone0809 (Zeeland) (github.com)
- 🎉 支持我:点赞👍+收藏⭐️+留言📝
- 📣 系列专栏:Python系列专栏 🍁
- 💬介绍:The mixture of software dev+Iot+ml+anything🔥
Python开源项目
- 【cushy-storage】一个基于磁盘缓存的Python框架
- 【cushy-socket】 一款轻量级的Python Socket框架
- 【cushy-serial】 一个轻量级Python serial库
- 【broadcast-service】一个轻量级Python发布订阅者框架
- 【Python实战】从架构设计到实现:一个Powerful的图书管理系统
前言
随着数据和信息的大量增长,多数用户都需要更加安全和保护自己的隐私。有很多选项可以帮助我们实现这一目的,其中JSON Web Token(JWT)是一种有效的解决方案。pyjwt是一种开源的Python库,可以生成、验证和编码JWT。
在本篇博客中,我将介绍pyjwt的主要特点和功能。同时,我还将探讨JWT的概念、加密和解密过程以及JWT的优点。此外,我将分享使用pyjwt时遇到的问题以及解决方案。
而pyjwt是一个十分轻量级的框架,基本上可以做到开箱即用,
JSON Web Token概述
JSON Web Token(JWT)是一种用于在网络上传输数据的标准。JWT是通过两个不同实体之间的安全通道进行传输的一种信息,其中包含了某些关键信息和元数据。JWT拥有广泛的应用场景,可以在Web开发中用于授权、身份验证,以及安全通讯等方面
JWT通常由三个部分组成:
Header
Header部分包含了JWT的元数据,包括令牌类型和加密算法等信息。常用的令牌类型包括JWT和Bearer。常用的加密算法包括HS256、RS256和ES256等等。
Payload
Payload部分是JWT的主体,它包含了用户的信息数据。Payload可以是各种格式,通常是包含用户ID、姓名、电子邮件、角色等重要信息的JSON格式数据。
Signature
Signature部分是JWT的签名,它是针对Header和Payload部分的哈希算法。Signature可以用于验证JWT的合法性。
快速开始使用pyjwt
在开始使用pyjwt之前,首先需要使用pip安装它。
$ pip install pyjwt
在安装之后,你可以从一个字符串创建一个JWT Token,并选择适当的加密算法。
import jwt
encoded_token = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256')
在这个例子中,JWT的Payload是{‘some’: ‘payload’},加密算法是HS256。'secret'
就是用于生成签名的密钥。
要验证JWT Token是否有效,你需要提供一个与你生成JWT时使用的相同的密钥。
decoded_token = jwt.decode(encoded_token, 'secret', algorithms=['HS256'])
在这个例子中,我们验证了Token的合法性,并且需要使用与加密时相同的algorithm
参数。如果JWT Token无效,将会抛出异常。
pyjwt的高级用法
在熟悉了pyjwt的基本用法之后,你还可以使用更多的特性来传递额外的信息。
在Token中添加过期时间
你可以通过添加exp
字段实现Token的有效期。使用datetime库中的datetime和timedelta可以生成一个具有一小时时效性的Token。
from datetime import datetime, timedelta
expiration_date = datetime.utcnow() + timedelta(hours=1)
payload = {'exp': expiration_date, 'sub': '12345'}
token = jwt.encode(payload, 'secret', algorithm='HS256')
在Token中添加角色权限
你可以向JWT的Payload中添加更多的应用程序特定标记,例如角色权限。
payload = {'role': 'admin', 'exp': expiration_date, 'sub': '12345'}
token = jwt.encode(payload, 'secret', algorithm='HS256')
定制Payload查询
在很多情况下,你可能需要检索JWT Token的Payload信息。为了执行此操作,可以使用decode
方法并指定verify_signature=False
参数。
decoded_token = jwt.decode(token, options={"verify_signature": False})
print(decoded_token['exp'])
在需要使用过期或角色权限信息的情况下,这种方式非常有用。
实现单点登录
使用JWT和pyjwt的基本特性和优点可以实现一个可扩展的和高效的单点登录(SSO)解决方案。其中,JWT token是SSO方案的核心。
JWT的优点
JWT有许多优点。
安全性
HTTPS正常情况下是足够安全的,但是就算没有HTTPS,JWT照样具有安全性。JWT体积不大,能够轻易地跨越不同的客户端和服务器。此外,当协议是基于令牌的时候,令牌中的信息可以进行良好的加密和解密,并且令牌在被篡改的情况下会被相应的使用者发现。
可伸缩性
JWT Token可以通过扩展在多个服务器间进行分发,并且可以在不损失安全性的前提下实现多个应用之间的协作。例如,可以使用JWT令牌在不同的微服务之间共享全局状态和授权信息。
状态无关性
在一些情况下,应用需要一个状态无关机制,这样用户的状态可以保存更长时间,而不会受到应用服务器的限制。JWT Token提供了这种机制,如果要扩展,这种机制还可以在多个应用之间进行共享。
遇到的问题和解决方案
在使用pyjwt时,我遇到了许多问题,但最终都找到了解决方案。
问题1:无法对pyjwt按照预期解码,并显示中文
# Encoding
payload = {'username': 'john', 'pswd': '123456', '大学': '清华大学'}
secret = 'secret_key'
token = jwt.encode(payload, secret, algorithm='HS256')
# Decoding
data = jwt.decode(token.decode('utf-8'), secret, algorithms='HS256')
在运行上述代码时,我无法按预期获得中文,结果只显示{'username': 'john', 'pswd': '123456', '\xe5\xa4\xa7\xe5\xad\xa6': '\xe6\xb8\x85\xe5\x8d\x8e\xe5\xa4\xa7\xe5\xad\xa6'}
。
解决方案:在encode
方法中指定utf-8
编码项即可。
# Encoding
payload = {'username': 'john', 'pswd': '123456', '大学': '清华大学'}
secret = 'secret_key'
token = jwt.encode(payload, secret, algorithm='HS256')
# Decoding
data = jwt.decode(token.decode('utf-8'), secret, algorithms='HS256', options={'verify_exp': False},verify=True)
print(data)
问题2:PyCharm报错:“module ‘jwt.exceptions’ has no attribute ‘DecodeError’”
在我的PyCharm开发环境中,当我使用jwt.exceptions.DecodeError
时,PyCharm报错说该模块没有该属性。
解决方案:这个问题是因为我使用的是PyJwt库,并且它具有自己的异常定义。正确的方法是使用jwt.DecodeError
,因为它直接来自于PyJWT库。
问题3:如何禁用过期验证?
默认情况下,decode
方法将验证过期时间。如果你需要关闭过期验证,你需要在调用decode
方法时指定verify_exp=False
。
decoded_token = jwt.decode(token, 'secret', algorithms=['HS256'], verify_exp=False)