JWT详解以及在python中的使用

617 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

摘要:本文介绍JWT的header,payload,以及签名的组成成分,以及如何在python中使用JWT

JWT 全称Json Web Roken。是一种较为新型的用户验证机制。

JWT认证流程

  1. 客户端输入账号密码发起请求;
  2. 服务端收到请求,验证账号密码正确生成jwt,并发送到客户端;
  3. 用户收到jwt;
  4. 用户再次发送请求并携带jwt;
  5. 服务端收到带有jwt的请求后,首先验证jwt的正确性,正确则返回相应;

1、JWT包含三部分:

1.1、头部header:

头部就是用来声明一些数据使用的,以字典的形式展示,可以存储类型typ,加密方式alg等信息,头部信息会经过base64编码。注意base64不是一种加密方式,只是一种存储数据的手段,许多文章都说加密也是服了。

headers = {
    'typ': 'JWT',
    'alg': 'HS512'  # 默认的加密方式为HS256,
}
jku: 发送JWK的地址;最好用HTTPS来传输
jwk: 就是之前说的JWK
kid: jwk的ID编号
x5u: 指向一组X509公共证书的URL
x5c: X509证书链
x5t:X509证书的SHA-1指纹
x5t#S256: X509证书的SHA-256指纹
typ: 在原本未加密的JWT的基础上增加了 JOSE 和 JOSE+ JSON。JOSE序列化后文会说及。适用于JOSE标头的对象与此JWT混合的情况。

crit: 字符串数组,包含声明的名称,用作实现定义的扩展,必须由 this->JWT的解析器处理。不常见。

官网摘录的加密算法的种类: 数字签名算法 — PyJWT 2.4.0 文档

1.2、载荷payload:

顾名思义就是承载数据具体输信息的,这里的信息不包括隐私数据,因为这个也是base64编码存储的,这也就意味着任何人都可以获取你的payload部分的数据,你可以存储用户id,JWT过期时间,发布时间等信息。也可以添加一些自定义键值对。

payload_dict = {
    'user_id': user_id,  # 自定义字段信息
    'iss': iss,  # 发布者信息
    'iat': now_time,
    'exp': now_time + exp,
可存放的字段有:
iss 发布者的信息
sub 该JWT所面向的用户,用于处理特定应用,不是常用的字段
aud 接受者的url地址
exp 该jwt销毁的时间;unix时间戳
nbf 该jwt的使用时间不能早于该时间;unix时间戳
iat 该jwt的发布时间;unix 时间戳
jti 该jwt的唯一ID编号
}

签证 signature

该部分由header,payload经过base64编码后再经由加密算发加密后的到,在加密的过程中可以进行加盐处理,以确保数据的安全性。也就是说这部分的数据信息你要保证除了服务端知道怎么处理外其他任何端都不能知道。

在python中使用JWT

import jwt

class Jwt(object):
    def __init__(self,
                 user_id,
                 iss='Genowis',
                 exp=600,
                 salt='/*kifq^@!#$asd%hivxp^-=-2=3585maldnga.]',
                 algorithm="HS512"):
        self.headers = {
            'typ': 'JWT',
            'alg': algorithm
        }
        now = time.time()
        self.payload_dict = {
            'user_id': user_id,
            'iss': iss,
            'iat': now,
            'exp': now + exp,

        }
        self.salt = salt
        self.algorithm = algorithm

    def create(self):
        jwt_token = jwt.encode(self.payload_dict,
                               key=self.salt,
                               algorithm=self.algorithm,
                               headers=self.headers)

        return jwt_token

    def check(self, token):
        data = jwt.decode(token, self.salt, algorithms=self.algorithm)
        return data
        
if __name__ == '__main__':
    j = Jwt('asfgbdgbafaafsdfgbb')
    data = j.create()
    print(data)