Django入门教程

前言

第一章: django快速入门

第二章: django MTV架构

第三章: django视图

第四章: django模板

第五章: django模型

第六章: django后台管理系统

第七章: 项目实战-简易的博客系统

第八章:django表单

第九章:django用户认证系统

第十章:django中的会话

第十一章:django安全

第十二章:django性能优化

第十三章:django实用工具

首页 > Django入门教程 > 第十一章:django安全 > 11.3节:数据签名

11.3节:数据签名

薯条老师 2020-10-13 06:54:30 232849 0

编辑 收藏

系统地讲解Django开发的基础知识, 高阶知识。关注微信公众号[薯条编程],领取该教程的PDF电子书:《Python web开发-django从入门到精通》。

11.3.1 django数据签名

执行startproject命令创建一个django项目时,django会生成一个随机密钥,其保存在settings.py的全局变量SECRET_KEY中。该密钥用于对签名的数据进行加密,打开settings.py,可以找到这个全局变量SECRET_KEY:

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'c_is=00rh8cv72qxv)r06t$7i7lum@18-=4j@6m6sjde+urxh0'

用户通过登录认证以后,可以使用django内置的签名模块对会话信息进行数据签名,以检测数据是否被篡改。django提供了两个基础类型对数据进行加密签名,分别为Signer与TimestampSigner。

TimestampSigner在Signer的基础上给已签名的数据添加了时间戳,以检测签名数据是否过期。

对于复杂的数据结构类型,比如字典对象,可以使用signing模块中的dumps方法来生成数据签名。

11.3.2 Signer类型

在程序中使用Signer类型,需要从django.core.signing中导出:

from django.core.signing import Signer

Signer类型的构造函数:

Signer.__init__(self, key=None, sep=':', salt=None)

参数解释:

(1) key表示用来加密的密钥,默认为settings.py中的SECRET_KEY

(2) sep用来定义数据与签名信息之间的分隔符,默认为:

(3) salt用来在加密时进行算法的加盐处理。

Signer对象的主要方法:

方法名

描述

Signer.sign(value)

生成value值的签名数据

Signer.unsign(signed_value)

返回签名前的原始数据,参数signed_value表示已签名的数据。在校验过程中,数据一旦被篡改,即会抛出BadSignature的错误异常

同学们可以进入django shell中测试,按照以下步骤进入django的shell环境:

(1) 进入windows命令行,切换到项目所在目录

(2) 执行python manage.py shell命令,进入django shell


D:\django-project>python manage.py shell

Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.

(InteractiveConsole)

>>>

使用SECRET_KEY来生成签名数据:

>>> from django.core.signing import Signer

>>> signer = Signer()

>>> signed_value = signer.sign("backer")

>>> signed_value

'backer:mXLNe8rzcMnij2_9eMbzdUCR3Hk'

对签名数据进行校验,如果数据篡改,那么会抛出BadSignature的错误异常:

>>> signer.unsign(signed_value)

'backer'

# 对signed_value进行修改

>>> signed_value +='S'

>>> signer.unsign(signed_value)

Traceback (most recent call last):

  File "<console>", line 1, in <module>

  raise BadSignature('Signature "%s" does not match' % sig)

django.core.signing.BadSignature: Signature "mXLNe8rzcMnij2_9eMbzdUCR3HkS" does not match

使用自定义的密钥来生成签名数据,以及校验:

>>> signer = Signer(key="@#$%^")

>>> signed_value  = signer.sign("backer")

>>> signed_value

'backer:vDC5IvftPrdIO8yeeDDkDjnW39s'

>>> signer.unsign(signed_value)

'backer'

创建数据签名时,可以使用salt参数对签名过程进行加盐处理:

>>> signer = Signer(salt="algorithm need salt")

>>> signed_value = signer.sign("backer")

>>> signed_value

'backer:raVHz8t3m0Mb0lxKBJD1taTIfzs'

>>> signer.unsign(signed_value)

'backer'

11.3.3 TimestampSigner类型

TimestampSigner是Signer类型的子类,它在Signer的基础上给已签名的数据添加了时间戳,以检测签名数据是否过期。在程序中使用TimestampSigner类型,需要从django.core.signing中进行导出:

from django.core.signing import TimestampSigner

TimestampSigner类型的构造函数:

Signer.__init__(self, key=None, sep=':', salt=None)

参数解释:

(1) key表示用来加密的密钥,默认为settings.py中的SECRET_KEY

(2) sep用来定义数据与签名信息之间的分隔符,默认为:

(3) salt用来对数据加密时进行算法的加盐处理。

TimestampSigner对象的主要方法:

方法名

描述

Signer.sign(value)

生成value值的签名数据

Signer.unsign(signed_value,max_age=None)

signed_value表示已签名的数据,max_age可传递整型(秒数)或datetime.timedelta类型,表示签名数据的有效时间。签名数据如果过期,会抛出SignatureExpired的错误异常。

使用TimestampSigner对象检测签名数据是否过期:

>>> signed_value  = signer.sign("backer")

>>> signer.unsign(signed_value, 10)

'backer'

>>> signer.unsign(signed_value, 10)

'backer'

>>> signer.unsign(signed_value, 10)

django.core.signing.SignatureExpired: Signature age 10.357650756835938 > 10 seconds

11.3.4 signing模块

signing模块提供了dumps方法对复杂的数据结构类型进行加密签名。在程序中使用signing模块,需要从django.core中导出:

from django.core import signing

signing模块的主要方法:

方法名

描述

dumps(obj,key=None,salt='django.core.signing', compress=False

生成复杂数据类型的签名数据,返回字符串类型。

obj表示待签名的数据类型。

key表示用来加密的密钥,默认为settings.py中的SECRET_KEY。

salt用来在加密时进行算法的加盐处理。

compress表示是否对签名数据进行压缩。

 

loads(string,key=None,salt='django.core.signing', max_age=None)

将string参数表示的签名数据进行反序列化,max_age表示签名数据的有效期。

使用signing模块来对字典类型进行签名,并检测是否过期:

>>> from django.core import signing

>>> signed_value = signing.dumps({"name":"backer"})

>>> signed_value

'eyJuYW1lIjoiYmFja2VyIn0:1id3DD:g-DEOvKvcup7xFqU010TZen3kII'

>>> signing.loads(signed_value)

{'name': 'backer'}

>>> signing.loads(signed_value,max_age=50)

{'name': 'backer'}

>>> signing.loads(signed_value,max_age=30)

django.core.signing.SignatureExpired: Signature age 36.79613471031189 > 30 seconds

关注微信公众号:薯条编程,公众号后台回复"Python资料",免费领取Python电子书,以及学习Python视频课程。

小班授课,薯条老师一对一教学,火热报名中,点击了解线下就业培训。


欢迎 发表评论: