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类中含有序列化进行一个加密 并且可以添加对时间的控制

django 从零开始 11 根据时间戳加密数据

其实就是将上面的 TimestampSigner 类的时间戳加密弄过来了 返回一串加密字符          其中默认使用当时时间戳进行时间认证 不像flask在进行加密时可以确认过期时间 相反

 django 从零开始 11 根据时间戳加密数据

 

可以保存到cookies中,进下一个页面需要验证使用这个验证(ps在这cookies卡了好久,我还以为咋cookeis没传过去,一直是空的 原来需要HttpResponse设置...)

 


 

 

解密sign 值

同样也是 TimestampSigner 的时间戳解密  源码如下

django 从零开始 11 根据时间戳加密数据

key和sigin加密一样默认不设置,先以简单为主     

其中有一个参数max_age(用来对比时间)  unsign解密源码

django 从零开始 11 根据时间戳加密数据

 

比如你是在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)

 

 

结果 

django 从零开始 11 根据时间戳加密数据

 

获取不过期的sign  并得到结果 传入dict得到dict

django 从零开始 11 根据时间戳加密数据

 

对比设置解密时间过期 结果

django 从零开始 11 根据时间戳加密数据

 

 设置的20秒过期  设置sign时间为20:42:23   获取sign的时间为20:43:38  哪怕能获取到sign值,也会解密错误