jwt的使用
jwt官网:https://jwt.io/
1.header
{‘alg’:‘HS256’, ‘typ’:‘JWT’}
2.payload
{
‘exp’:xxx, # Expiration Time 此token的过期时间的时间戳
‘iss’:xxx,# (Issuer) Claim 指明此token的签发者
‘aud’:xxx, #(Audience) Claim 指明此token的
‘iat’:xxx, # (Issued At) Claim 指明此创建时间的时间戳
‘aud’:xxx, # (Audience) Claim 指明此token签发面向群体
}
3.sign
HS256(自定义的key , base64后的header + ‘.’ + base64后的payload)
jwt格式
base64(header) + ‘.’ + base64(payload) + ‘.’ + base64(sign)
代码
import base64
import copy
import hmac
import json
import time
class Jwt(object):
def __init__(self):
pass
@staticmethod
def b64encode(content):
# 去掉多余的 =号
return base64.urlsafe_b64encode(content).replace(b'=', b'')
@staticmethod
def b64decode(b):
# 把去掉的=号加回来
sem = len(b) % 4
if sem > 0:
b += b'=' * (4 - sem)
return base64.urlsafe_b64decode(b)
# 编码
@staticmethod
def encode(payload, key, exp=300):
# 初始化头 init header
header = {'typ': 'JWT', 'alg': 'HS256'}
header_json = json.dumps(header,
separators=(',', ':'), # 紧凑字符串
sort_keys=True) # 有序性
header_bs = Jwt.b64encode(header_json.encode())
# 初始化数据 init payload
payload_self = copy.deepcopy(payload)
if not isinstance(exp, int) and not isinstance(exp, str):
raise TypeError('Exp must be int or str !')
exp_time = time.time() + int(exp)
print(exp_time)
payload_self['exp'] = exp_time
payload_js = json.dumps(payload_self,
separators=(',', ':'), # 紧凑字符串
sort_keys=True)
print(payload_js)
# json => base64
payload_bs = Jwt.b64encode(payload_js.encode())
# 初始化签名 init sign
if isinstance(key, str):
key = key.encode()
# 计算签名
hm = hmac.new(key, header_bs + b'.' + payload_bs, digestmod='SHA256')
# json => base64
sign_bs = Jwt.b64encode(hm.digest())
# 组合token
return header_bs + b'.' + payload_bs + b'.' + sign_bs
@staticmethod
def decode(token, key):
header_bs, payload_bs, sign_bs = token.split(b'.')
# 校验签名
if isinstance(key, str):
key = key.encode()
hm = hmac.new(key, header_bs + b'.' + payload_bs, digestmod='SHA256')
print(sign_bs)
print(Jwt.b64encode(hm.digest()))
if Jwt.b64encode(hm.digest()) != sign_bs:
print('签名校验失败!')
raise
# 检查 exp是否过期
payload_js = Jwt.b64decode(payload_bs)
payload = json.loads(payload_js)
if 'exp' in payload:
now = time.time()
if now > payload['exp']:
print('exp 校验失败')
raise
# return payload部分的解码
return payload
if __name__ == '__main__':
token = Jwt.encode({"username": "hzx"}, '12345', 300)
print('生成token')
print(token)
print('校验结果')
print(Jwt.decode(token, '12345'))
pyjwt
安装
pip install jwt
使用代码
import time
import jwt
payload = {'username': 'hzx',
'exp': time.time() + 2, # 超时时间
'iss': 'wo'} # 发布者
token = jwt.encode(payload,
'123456', # key
algorithm='HS256') # 加密算法
print(token, type(token))
a = jwt.decode(token, # 令牌
'123456', # key
algorithms='HS256', # 加密算法
issuer='wo') # 校验发布者
print(a)
time.sleep(3)
# token过期 raise ExpiredSignatureError("Signature has expired")
# a = jwt.decode(token, '123456', algorithms='HS256')
# print(a)
输出结果
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imh6eCIsImV4cCI6MTYxNDE1ODQyMC4zMTE2Mjk1LCJpc3MiOiJ3byJ9.9xm5N5w12c52DmXqw35WCZoBmzU8oyj8Pcx56XKhFiI
<class 'str'>
{'username': 'hzx', 'exp': 1614158420.3116295, 'iss': 'wo'}