Flask签名验证
Posted Flask学习笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask签名验证相关的知识,希望对你有一定的参考价值。
itsdangerous
一般在网站中使用
cookie\session
来处理用户登录等权限问题,有时也会使用token
的方式.每次用户发出需要身份认证的请求时,就需要验证一次token
是否生效,这就会涉及到签名的问题,在向不可信的环境中发送数据时,确保数据经过签名,并且只有自己有秘钥.
itsdangerous
这个插件包含了很多验证的方案.使用HMAC\SHA1
来签名,支持JSON WEB SIGNATURE(JWS)
.
1.安装
$ pip install itsdangrous
官网(
https://itsdangerous.palletsprojects.com/en/1.1.x/
)
2.得定字符串签名
发送方和接收方拥有相同的秘钥.发送方使用秘钥对内容进行签名,接收方使用相同的秘钥对内容进行验证.
>>> from itsdangerous import Signer
>>> s = Signer('secret-key')
>>> s.sign('my string')
'my string.wh6tMHxLgJqB6oY1uT73iMlyrOA'签名后字符串使用
.
分割,验证使用unsign
>>> s.unsign('my string.wh6tMHxLgJqB6oY1uT73iMlyrOA')
上文给出的
secret-key
是一个随意的字符串,如果你需要更无序的字符串,可以使用os.urandom
3.带时间戳的签名
如果要有时效性的签名,,可以带上时间信息
>>> from itsdangerous import TimestampSigner
>>> s = TimestampSigner('secret-key')
>>> string = s.sign('foo')
foo.DlGDsw.dpJ37ffyfNAVufH21lH_yoelnKA
>>> s.unsign(string, max_age=5)
4.序列化
Serializer
提供了一个dumps/loads
接口,类似与python
的json
模块,该接口将对象序列化为字符串,然后进行签名.>>> from itsdangerous import Serializer
>>> s = Serializer('secret-key')
>>> s.dumps([1, 2, 3, 4])
>>> s.loads('[1, 2, 3, 4].r7R9RhGgDPvvWl3iNzLuIIfELmo')
1.带时间戳的序列化
>>> from itsdangerous import TimedSerializer
>>> s=TimedSerializer('secret-key')
>>> string = s.sign('foo')
>>> s.unsign(string, max_age=5)
2.URL
安全序列化
如果加密后的字符串需要在
URL
中传输,可以使用这种方式.常见的是在邮箱中验证token
>>> from itsdangerous import URLSafeSerializer
>>> s = URLSafeSerializer('secret-key')
>>> s.dumps([1, 2, 3, 4])
'WzEsMiwzLDRd.wSPHqC0gR7VUqivlSukJ0IeTDgo'
>>> s.loads('WzEsMiwzLDRd.wSPHqC0gR7VUqivlSukJ0IeTDgo')
[1, 2, 3, 4]
3.JSON WEB SIGNATURE
JWS
是一种基于JSON
数据结构的签名的算法规范.详细规定请点击
itsdangerous
基于JWS
实现了URL
安全序列化from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
s = Serializer('secret-key', expires_in=60) # exprs_in是过期时间
s.dumps({'id': user.id}) # user 为 model 中封装过的对象
5.在Flask
中使用
- END -from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from config import config
def gen_token(user, expiration=1440*31*60): # 单位为秒,设定 31 天过期
s = Serializer(config.SECRET_KEY, expires_in=expiration)
return s.dumps({'id': user.id}) # user 为 model 中封装过的对象装饰器
from functools import wraps
def token_required(func):
@wraps(func)
def wrapper(*args, **kwargs):
token = request.form['token']
s = Serializer(config.SECRET_KEY)
try:
data = s.loads(token)
except SignatureExpired:
return jsonify({'status': 'fail', 'data': {'msg': 'expired token'}})
except BadSignature:
return jsonify({'status': 'fail', 'data': {'msg': 'useless token'}})
kwargs['user_id'] = data['id']
return func(*args, **kwargs)
return wrapper
以上是关于Flask签名验证的主要内容,如果未能解决你的问题,请参考以下文章
twilio.js 浏览器软件电话 - JWT 签名验证问题(Mac OSX / Chrome)
小知识点Python Flask 中使用 cryptography 模块实现加密