一、作用
可以利用itsdangerous模块支持JSON WEB签名。
二、使用
1、加密
from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer
from itsdangerous import BadData
secret_key= 'afesjyrtrw6457t'
expires_in = 300 # 有效期单位为秒
def generate_token()
# serializer = TJWSSerializer(秘钥, 有效期单位为秒)
serializer = TJWSSerializer(SECRET_KEY, expires_in )
# serializer.dumps(数据), 返回bytes类型,比如对用户的id和email进行加密返回前端
data = {
'id': user.id,
'email':user.email
}
token = serializer.dumps(data) # data为要加密的数据
token = token.decode() # 得到返回后的带有效期和用户信息的加密token
return token
2、解密
from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer
from itsdangerous import BadData
# 检验token(secret和有效期(expires_in)需要与生成时一致)
def check_token(token):
# 验证失败,会抛出itsdangerous.BadData异常
serializer = TJWSSerializer(secret_key, expires_in )
try:
# 获取解密后的数据 bytes:dict
data = serializer.loads(token)
except BadData:
return None
else:
user_id = data.get('id')
user_email = data.get('email')
try:
user = User.objects.get(id=user_id,email=user_email)
except User.DoesNotExist:
return None
else:
return user
三、加密原理
1、了解header
以下是header的数据,alg 为加密方法 这里默认使用的是SHA256 iat为保存时间 exp 为过期时间
{"alg":"HS256","iat":1554802652,"exp":1554802952}
2、了解paload
下面的json就是paload这也是我们存进去的数据
{"id":123}
3.、分别对header和paload进行base64编码并用‘.’拼接。这是itsdangerous包内的实现
base64d_header = base64_encode(self.serializer.dumps(header))
base64d_payload = base64_encode(self.serializer.dumps(obj))
return base64d_header + b'.' + base64d_payload
4、接下来就是需要去获取签名sign
签名的算法是将三步骤中的到的字符串 和我们定义的秘钥进行Hmac Sha256,再进行base64编码得到sign
5、组装成token
将4步骤的到的sign 和3步骤得到的拼接字符串 ,通过点进行拼接得到最后的token,一下为样例
eyJhbGciOiJIUzI1NiIsImlhdCI6MTU1NDgwMjY1MiwiZXhwIjoxNTU0ODAyOTUyfQ.eyJpZCI6MTIzfQ.p20JnbpentcEsLmJLCDFrZt3ft7tKrxIs-FU8olK2hw
以上就是itsdangerous的加密过程了,下面来看如何进行解密。
四、解密原理
1、通过上面的了解,我们知道token是通过两个点进行拼接,所以第一步我们就通过点进行切分字符串得到三个字符串分别是base64(header) base64(paload) base64(sign)
2、验证sign的签名有没有被修改过。
将base64(header)+‘.’+base64(paload) 与秘钥进行Hmac Sha256 加密,再通过base64编码得到签名,通过与base64(sign) 比对相同则说明签名没被篡改。
五、注意事项
itsdangerous加密解密非常类似JWT单点登录加密原理。因为paload部分都是可以进行Base64反向解密的,所以都不适合用于传输敏感信息。