前情提要

好久没更新过博客了,昨日工作室开会大佬们强调了博客的重要性,记博客不仅仅有利于后来者的学习,还有利于自己日后的反省检阅,更为重要的是,博客可以让自己的学习效果具象化。

这几天没什么拿出手的东西,那么我就分享下我最近写的jwt认证库吧(思路是照着别人写的,python在jwt上似乎还没有什么很好的轮子,,)

昨天有些人提到自己的token储存在redis上,其实token存在的意义就是为了减少服务器的负担,用加密验证形式以代替查表验证。

不说了,上码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/python3.8
import time
import json
import base64
import hashlib
import hmac


class jwt212:
def login_create_token(studentId,password,identity):#登陆时用,分配token。用于检验信息正确之后,此函数无检验功能
exp = 114514#过期,需再次登录。


headers = {
"typ": "token",
"exp": int(time.time() + exp) # 过期时间戳
}

payload = {
"studentId":studentId ,
"identity":identity
}

# 生产header
first = base64.urlsafe_b64encode(json.dumps(headers, separators=(',', ':')).encode('utf-8').replace(b'=', b'')).decode('utf-8').replace('=', '')
# 生成payload
second = base64.urlsafe_b64encode(json.dumps(payload, separators=(',', ':')).encode('utf-8').replace(b'=', b'')).decode('utf-8').replace('=', '')
first_second = f"{first}.{second}"
# 生成签名
third = base64.urlsafe_b64encode(hmac.new(password.encode('utf-8'), first_second.encode('utf-8'), hashlib.sha256).digest()).decode('utf-8').replace('=','')

# 拼接成token
token = ".".join([first, second, third])
return token


def token_check(token,password):##一定要提供密码
token_header=token.split()[0]
token=token.split()[1]
headers_check = token.split(".")[0]#头部
payload_check = token.split(".")[1]#内容
sign_check = token.split(".")[2]#签名
# 对数据签名、判断token上对签名是否是合规对
headers_payload_check = f"{headers_check}.{payload_check}"
new_sign = base64.urlsafe_b64encode(hmac.new(password.encode('utf-8'), headers_payload_check.encode('utf-8'), hashlib.sha256).digest()).decode('utf-8').replace('=','')
#下面解码,看时间对不对
################################
if isinstance(headers_check, str):
headers_check = headers_check.encode('ascii')
rem = len(headers_check) % 4
if rem > 0:
headers_check += b'=' * (4 - rem)
# 上面这一部分是解密的部分数据补全格式
header_data = base64.urlsafe_b64decode(headers_check) # 解码
data = json.loads(header_data)

time_past=int(data.get("exp"))#获取过期时间
time_right_now=int(time.time()) #获取现在时间
if sign_check==new_sign and time_right_now<=time_past and token_header=="Bearer":#检查签名合法和时间
return True
else:
return False



def token_query(token):
payload = token.split(".")[1]#内容
################################
if isinstance(payload, str):
payload = payload.encode('ascii')
rem = len(payload) % 4
if rem > 0:
payload += b'=' * (4 - rem)
############################################################
payload_data = base64.urlsafe_b64decode(payload) # 解码
data = json.loads(payload_data) # 将已编码的JSON字符串解码为Python对象,即将payload转为可以通过get方法获取里面的值
return data # 返回payload的数据

如何使用

1
2
3
4
5
import filename
app=filename.jwt212