django自带一个加密的方法signer,对数据进行一个加密
一般这种方式用于账号密码邮箱找回,或者token设置
class TimestampSigner(Signer): def timestamp(self): return baseconv.base62.encode(int(time.time())) def sign(self, value): value = '%s%s%s' % (value, self.sep, self.timestamp()) return super().sign(value) def unsign(self, value, max_age=None): """ Retrieve original value and check it wasn't signed more than max_age seconds ago. """ result = super().unsign(value) value, timestamp = result.rsplit(self.sep, 1) timestamp = baseconv.base62.decode(timestamp) if max_age is not None: if isinstance(max_age, datetime.timedelta): max_age = max_age.total_seconds() # Check timestamp is not older than max_age age = time.time() - timestamp if age > max_age: raise SignatureExpired( 'Signature age %s > %s seconds' % (age, max_age)) return value
这是django文档中的源码 ,可以看到是继承自signer类的,其中sign函数是对输入的数据加上当前时间戳进行一个加密
unsign则是验证加密数据是否过时,得到传入加密数据的时间戳,对函数中max_age时间转换为时间格式对比,如果当前时间减去加密数据的时间大于设置的规定时间,则抛出异常,不然返回正确的值
但是有个大问题,就是 加密数据会显示出来 比如加密数据{'name':'小明'} 会显示为' {'name':'小明'}:fszfdfyhYRTCFVDRSVG15R1X32B' 这种明显不行
后来在网上查找 发现sign类中含有序列化进行一个加密 并且可以添加对时间的控制
其实就是将上面的 TimestampSigner 类的时间戳加密弄过来了 返回一串加密字符 其中默认使用当时时间戳进行时间认证 不像flask在进行加密时可以确认过期时间 相反
可以保存到cookies中,进下一个页面需要验证使用这个验证(ps在这cookies卡了好久,我还以为咋cookeis没传过去,一直是空的 原来需要HttpResponse设置...)
解密sign 值
同样也是 TimestampSigner 的时间戳解密 源码如下
key和sigin加密一样默认不设置,先以简单为主
其中有一个参数max_age(用来对比时间) unsign解密源码
比如你是在1点10分进行一个加密,加密sign数值中含有1点10分的时间,使用unsign解密 输入max_age=60 数值为秒 不设置则为永久存在
解密过程中对比 将时间格式化 当前解密时的时间 减去 加密的时间 得到相减的时间 如果大于设置过期时间 抛出异常 不然返回解密值
所以我的代码是
加密
from datetime import datetime from django.core import signing def set_sign(request): value = signing.dumps({'user':1254,'name':'xiaoming小明'}) print(value) request.COOKIES['sign'] = value req = HttpResponse('获取sign值成功') req.set_cookie('sign',value) return req
解密
def get_sign(request): value = request.COOKIES.get('sign') print(value) s = '没有获取到sign' if value: try: s = signing.loads(value,max_age=20) # 设置过期时间 print(s,datetime.now()) print(type(s)) # 加密时什么格式 返回什么格式 except: print('sign过期',datetime.now()) s = 'sign过期' return HttpResponse(s)
结果
获取不过期的sign 并得到结果 传入dict得到dict
对比设置解密时间过期 结果
设置的20秒过期 设置sign时间为20:42:23 获取sign的时间为20:43:38 哪怕能获取到sign值,也会解密错误
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:django 从零开始 11 根据时间戳加密数据 - Python技术站