用签名保护你的隐私(3)-URL安全序列化
在网络上进行数据传输是不安全的,必须的防止数据的伪造和篡改,特别是在web开发中使用GET传参的时候就更加要考虑这种需求,但GET传参是通过URL传参的,只能使用ASCII码,Itsdangerous模块中的URL安全序列化正好满足这种字符受限的情况。
URL安全序列化包括以下两个类:
- URLSafeSerializer
- URLSafeTimedSerializer
1.URLSafeSerializer
这个类的用法同Serializer差不多,但可以序列化和反序列化url安全的字符串,包括大小写英文字母和'_'、'-'、'.'
从继承的层次看URLSafeSerializer多了一个父类URLSafeSerializerMixin,这类功能是什么呢?下面是它的源码
class URLSafeSerializerMixin(object):
default_serializer = _CompactJSON
def load_payload(self, payload, *args, **kwargs): # 反序列化预处理
decompress = False
if payload.startswith(b"."):
payload = payload[1:]
decompress = True
try:
json = base64_decode(payload) # base64解码
except Exception as e:
raise BadPayload(
"Could not base64 decode the payload because of an exception",
original_error=e,
)
if decompress:
try:
json = zlib.decompress(json) # 解压缩
except Exception as e:
raise BadPayload(
"Could not zlib decompress the payload before decoding the payload",
original_error=e,
)
return super(URLSafeSerializerMixin, self).load_payload(json, *args, **kwargs)
def dump_payload(self, obj): # 序列化预处理
json = super(URLSafeSerializerMixin, self).dump_payload(obj)
is_compressed = False
compressed = zlib.compress(json) # 关键,压缩字符串
if len(compressed) < (len(json) - 1):
json = compressed
is_compressed = True
base64d = base64_encode(json) # 对字符串做base64编码
if is_compressed:
base64d = b"." + base64d
return base64d
从源代码看,这个类主要完成序列化和反序列化的预处理,在序列化预处理中,对要序列化的字符串进行压缩,然后再进行base64编码。所以它的子类URLSafeSerializer可以对特殊字符(_-.)进行处理。URLSafeSerializer用法和Serializer相同,如图2所示
2.URLSafeTimedSerializer
这个类和TimedSerializer用法差不多,但序列化(dumps)和反序列化(loads)url安全的字符串,包括大小写英文字母和'_'、'-'、'.'
URLSafeTimedSerializer也继承了URLSafeSerializerMixin,它会对字符串进行base64编码,所以也可以处理特殊字符。下面是它的用法:
import time
from itsdangerous.url_safe import URLSafeTimedSerializer
url_time_serializer = URLSafeTimedSerializer('ksdfkls903')
# 序列化
res = url_time_serializer.dumps([1,2,3])
# WzEsMiwzXQ.XoBQLA.0fRHds5_DwWfVqeorMSOU4ohz0U
print(res)
# 反序列化
# 没有时间限制
res = url_time_serializer.loads(res)
# [1, 2, 3]
print(res)
time.sleep(5) # 等等5秒
# 有时间限制
res = url_time_serializer.loads(res,max_age=3)
print(res)
其执行结果如图4所示。
URLSafeTimedSerializer可以对各种内置类型进行序列化,生成URL安全的字符串,并且可以限制过期时间,是非常理想的生成token的算法,所以在前后端分离的项目总可以使用URLSafeTimedSerializer生成token,在下一节中,我们将讨论token的生成。
喜欢的话请记得收藏点赞