python-jwt

JWT 介绍

JWT 即 JSON Web Token,是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准。

JWT 由三部分构成:

1 头部(Header):用于描述关于该 JWT 的最基本的信息,例如其类型以及签名所用的算法等。

2 载荷(Payload):payload 有五个字段

  1. iss:该 JWT 的签发者
  2. sub:该 JWT 所面向的用户
  3. aud:接收该 JWT 的一方
  4. exp:过期时间
  5. iat:签发时间

3 签名(Signature):header 与 payload 通过 header 中声明的加密方式,使用密钥 secret 进行加密,生成签名(也就是 token 值)。


为什么使用 JWT

之前用户身份认证广泛使用的是 session 机制,但是 session 机制存在以下问题:

  1. 随着客户端用户的增加,服务器的开销会明显增大
  2. 它是基于 cookie 来进行用户识别的, cookie 如果被截获,用户就会很容易受到跨站请求伪造的攻击。

比较而言,JWT 有着更大的优势。


代码讲解

安装
1
pip install pyjwt
生成 token
1
2
3
4
5
6
7
8
9
10
11
import jwt
from datetime import datetime, timedelta, timezone

payload = {
'name': 'silence',
'exp': datetime.now(tz=timezone.utc) + timedelta(hours=1),
}
key = "123"
algorithm = "HS256"

token = jwt.encode(payload=payload, key=key, algorithm=algorithm)

参数解释:

  • payload:数据载荷。exp 过期时间,是规定字段,它可以是 UTC 时间戳,也可以是 datetime 类型
  • key:加密密钥
  • algorithm:加密方式,默认为 HS256

验证 token
1
2
3
4
try:
data = jwt.decode(token, key=key, algorithms=algorithms)
except jwt.ExpiredSignatureError:
pass

如果生成 token 的时候添加了字段 exp,那么在 decode 的时候会自动验证是否过期,如果过期,则抛出 ExpiredSignatureError 错误。


封装
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
import jwt
from datetime import datetime, timedelta, timezone
from flask import current_app


class JWT():
def __init__(self, exp_hours):
self.hours = exp_hours
self.key = current_app.config['SECRET_KEY']
self.algorithm = 'HS256'

def generate_token(self, user_id):
dic = {
'exp': datetime.now(tz=timezone.utc) + timedelta(hours=self.hours),
'data': user_id
}

token = jwt.encode(dic, key=self.key, algorithm=self.algorithm)

return token


def verify_token(self, token):
try:
data = jwt.decode(token, key=self.key, algorithms=self.algorithm)
except:
return None

return data