一、背景
因为HTTP协议是无状态的(客户端向服务器发送请求,而服务响应完成后,客户端再次发送请求,服务器不认得上次是否请求的,属于提了裤子不认人的主),所以需要持久机制。服务器生成cookie或者token,用于身份验证权限验证
二、为什么使用token,而不是cookie
参考: ivyzhang
- token和cookie一样都是首次登陆时,由服务器下发,都是当交互时进行验证的功能,作用都是为无状态的HTTP提供的持久机制。
- 对于token而言,服务器不需要去查看你是谁,不需要保存你的会话,所以可扩展性强,当logout时候token只是注销浏览器信息,不查库。
- cookie需要查询存储在服务器上的session_id,方能验证当用户,logout的时候cookie和服务器的session都会注销
- cookie举例:服务员看你的身份证,给你一个编号,以后,进行任何操作,都出示编号后服务员去看查你是谁。
- token举例:说你告诉我你是谁就可以,直接给服务员看自己身份证
三、token状态保持方案
方案一 pyjwt
-
pip install pyjwt
- 简单示例
import jwt
from datetime import datetime, timedelta
expiry = datetime.utcnow() + timedelta(seconds=30)
secret = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9'
payload = {
'exp': datetime.utcnow() + timedelta(seconds=30), # 过期时间
'user_id': 10001,
'username': 'python'
}
# 加密
encoded_jwt = jwt.encode(payload, secret, algorithm='HS256')
print(encoded_jwt)
# 解密,校验签名
decode_jwt = jwt.decode(encoded_jwt, secret, algorithms=['HS256'])
print(decode_jwt)
# head部分.payload载荷部分.签名部分
方案二 itsdangerous
- ItsDangerous默认使用HMAC和SHA-512进行签名。
- 可以url加密参数,用来文件下载,设置几分钟内可以下载。
- 生成cookie,不用在服务器上存储会话,从而减少数据库查询次数
- 签名信息可以安全地在服务器和客户端之间进行往返,这使它们对于将服务器端状态传递给客户端然后再传递给客户端非常有用。
-
pip install itsdangerous
- 简单示例
from itsdangerous import TimedJSONWebSignatureSerializer
from itsdangerous import SignatureExpired, BadSignature, BadData
expiry = 60 * 60 * 30
secret = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9'
payload = {
'user_id': 10001,
'username': 'python'
}
# 加密
encrypt = TimedJSONWebSignatureSerializer(secret, expires_in=expiry)
token = encrypt.dumps(payload)
print(token)
# 解密,校验签名
decrypt = TimedJSONWebSignatureSerializer(secret, expires_in=expiry)
try:
payload = decrypt.loads(token)
except SignatureExpired:
print('token expired')
except BadSignature as e:
print('token bad signature')
print(payload )
四、pyjwt与itsdangerous区别
- **
pyjwt
**设置过期时间是utcnow() + 小时(分钟,天,秒),[日期时间 + 多少后过期] -
itsdangerous