序列化接口 — 这是危险的文档
序列化接口
签名接口 只对字符串进行签名。 为了对其他类型进行签名,Serializer
类提供了一个 dumps
/loads
接口类似于 Python 的 json
模块,它将对象序列化为一个字符串然后签名.
使用 dumps()
对数据进行序列化和签名:
from itsdangerous.serializer import Serializer
s = Serializer("secret-key")
s.dumps([1, 2, 3, 4])
b'[1, 2, 3, 4].r7R9RhGgDPvvWl3iNzLuIIfELmo'
使用 loads()
验证签名并反序列化数据。
s.loads('[1, 2, 3, 4].r7R9RhGgDPvvWl3iNzLuIIfELmo')
[1, 2, 3, 4]
默认情况下,数据被序列化为 JSON。 如果安装了 simplejson,则优先于内置的 json
模块。 这个内部序列化器可以通过子类化来改变。
要记录和验证签名的年龄,请参阅 使用时间戳签名 。 要序列化为可在 URL 中安全使用的格式,请参阅 URL 安全序列化 。
盐
所有类也接受盐参数。 该名称可能具有误导性,因为通常如果您想到密码学中的盐,您会期望盐与结果签名字符串一起存储,以防止彩虹表查找。 这种盐通常是公开的。
在它的危险中,就像在原始 Django 实现中一样,salt 有不同的用途。 您可以将其描述为命名空间。 如果您披露它仍然不重要,因为没有密钥就无法帮助攻击者。
假设您有两个要签名的链接。 您的系统上有可以激活用户帐户的激活链接,并且您有一个升级链接,可以将用户帐户升级为您通过电子邮件发送的付费帐户。 如果在这两种情况下您签署的只是用户 ID,则用户可以重复使用来自激活链接的 URL 中的变量部分来升级帐户。 现在,您可以在其中放置更多您签名的信息(例如意图:升级或激活),但您也可以使用不同的盐:
from itsdangerous.url_safe import URLSafeSerializer
s1 = URLSafeSerializer("secret-key", salt="activate")
s1.dumps(42)
'NDI.MHQqszw6Wc81wOBQszCrEE_RlzY'
s2 = URLSafeSerializer("secret-key", salt="upgrade")
s2.dumps(42)
'NDI.c0MpsD6gzpilOAeUPra3NShPXsE'
第二个序列化程序无法加载与第一个序列化程序一起转储的数据,因为盐不同:
s2.loads(s1.dumps(42))
Traceback (most recent call last):
...
itsdangerous.exc.BadSignature: Signature "MHQqszw6Wc81wOBQszCrEE_RlzY" does not match
只有具有相同盐的序列化程序才能加载数据:
s2.loads(s2.dumps(42))
42
应对失败
异常具有有用的属性,允许您在签名检查失败时检查有效负载。 这必须格外小心,因为那时您知道有人篡改了您的数据,但这可能对调试有用。
from itsdangerous.serializer import Serializer
from itsdangerous.exc import BadSignature, BadData
s = URLSafeSerializer("secret-key")
decoded_payload = None
try:
decoded_payload = s.loads(data)
# This payload is decoded and safe
except BadSignature as e:
if e.payload is not None:
try:
decoded_payload = s.load_payload(e.payload)
except BadData:
pass
# This payload is decoded but unsafe because someone
# tampered with the signature. The decode (load_payload)
# step is explicit because it might be unsafe to unserialize
# the payload (think pickle instead of json!)
如果您不想检查属性以找出究竟出了什么问题,您还可以使用 loads_unsafe()
:
sig_okay, payload = s.loads_unsafe(data)
返回的元组中的第一项是一个布尔值,指示签名是否正确。
应用程序接口