• JWT详细介绍


    每日阅读好习惯
    Python专栏文章:👉👉👉Python文章大全 | 有勇气的牛排🐮🐮🐮


    有问题的小伙伴欢迎在文末评论,点赞、收藏是对我最大的支持!!!

    1 🐮jwt介绍

    官网:https://jwt.io/
    本文以python来进行实战演示

    1.1 什么是jwt

    JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),它定义了一种紧凑且自包含的方式,用于以json的方式安全传输信息,并且通过数字签名来保证信息是信任的。jwt可以使用秘钥(HMAC算法)或RSA或ECDSA的公钥/私钥对其进行签名。

    1.2 使用场景

    1.2.1 授权

    用户在登录后,后续每个请求都将包含JWT,从而判断用户是否登录、是否有权限等操作。这种方式也被称为单点登录,其开销非常小,并且能够在不同的域中轻松使用。

    在Web开发中,我们通常会使用cookie或token的方式进行用户身份验证,jwt是属于token方法实现的一种,下面列出token方式的优点:

    • 支持跨域访问
    • 无状态:token本身就包含了用户信息,无需保存在服务端。
    • 适合移动端:如微信小程序、移动设备不支持cookie的客户端。
    • 无需考虑CSRF
    1.2.2 信息交换

    由于可以对JWT进行签名(例如:使用公钥/私钥),因此您可以确定数据发送者是否为本人。另外,由于使用标头和有效负载计算签名,我们可以验证内容是否被篡改。

    JWT最常见的场景就是授权认证,一旦用户登录,后续每个请求都讲包含JWT,系统在每次处理用户请求之前,都要先进行JWT安全校验,通过之后再进行处理。

    1.3 JWT结构

    JWT由3部分内容构成,并且以( . )作为分隔:

    格式:标题.有效载荷.签名/``

    1.3.1 header
    {
    	'alg':'HS256', 
    	'typ':'JWT'
    }
    
    • 1
    • 2
    • 3
    • 4

    alg:代表要使用的算法
    typ:代表token类别,这里为 大写 JWT

    此部分数据使用转为json并 base64 进行加密。

    1.3.2 payload

    1、共有声明(按需项,用户自定义添加)

    {
    	'exp':xxx, # Expiration Time 此token的过期时间的时间戳
    	'iss':xxx,# (Issuer) Claim 指明此token的签发者
    	'iat':xxx, # (Issued At) Claim 指明此创建时间的时间戳
    	'aud':xxx, # (Audience) Claim	指明此token签发面向群体
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、私有声明(用户自定义key、value)

    {
    	'username':'charles'
    }
    
    • 1
    • 2
    • 3

    转为json并用base64加密

    1.3.3 signature 签名

    这里要采用header中的算法进行,这里使用HS256算法

    # 伪代码
    HS256(自定义key, base64(header), base64(payload))
    
    • 1
    • 2

    2 🐮Python 实现

    2.1 手动编码

    """
        jwt生成
    """
    import json
    import time
    
    from common.util_encryption import hash_tool
    
    
    class Util_jwt:
        def __init__(self, header, payload, secret):
            self.header = header
            self.payload = payload
            self.secret = secret
    
        # 签名
        async def jwt_sign(self):
            bs_header = await hash_tool().get_base64(self.header)
            bs_payload = await hash_tool().get_base64(self.payload)
            s_group = bs_header + b'.' + bs_payload
            return hash_tool().get_sha256(self.secret, s_group)
    
        async def get_jwt_token(self):
            jwt_res = await hash_tool().get_base64(self.header) + b'.' + await hash_tool().get_base64(
                self.payload) + b'.' + await hash_tool().get_base64(await self.jwt_sign())
            return jwt_res
    
    
    jwt_header = json.dumps({'alg': 'HS256', 'typ': 'JWT'})
    jwt_payload = json.dumps({'exp': time.time() + 7200,  # Expiration Time 此token的过期时间的时间戳
                              'iss': 'couragesteak',  # (Issuer) Claim 指明此token的签发者
                              'iat': time.time(),  # (Issued At) Claim 指明此创建时间的时间戳
                              'data': {
                                  'username': 'charles'
                              }
                              })
    # 私钥
    secret = b"123456"
    
    import asyncio
    async def func():
        print("========jwt结果 异步==========")
        j = Util_jwt(header=jwt_header, payload=jwt_payload, secret=secret)
        print(await j.get_jwt_token())
    asyncio.run(func())
    
    • 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

    2.2 jwt包

    pip install pyjwt
    
    • 1

    加密

    class hash_tool:
    
        # 获取base64加密
        async def get_base64(self, data):
        # def get_base64(self, data):
    
            """
                data: str(字符串)
            """
            # 封装通用base64加密
            return base64.b64encode(data.encode())
    
        # 获取sha256加密
        async def get_sha256(self, secret, str):
            """
                key: 秘钥串
                str: 原文
            """
            hash = hashlib.sha256(secret)
            hash.update(bytes(str))
            return hash.hexdigest()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    异步实现

    """
        jwt生成
    """
    import json
    import time
    
    from common.util_encryption import hash_tool
    
    class Util_jwt:
        def __init__(self, header, payload, secret):
            self.header = header
            self.payload = payload
            self.secret = secret
    
        # 签名
        async def jwt_sign(self):
            bs_header = await hash_tool().get_base64(self.header)
            bs_payload = await hash_tool().get_base64(self.payload)
            s_group = bs_header + b'.' + bs_payload
            return hash_tool().get_sha256(self.secret, s_group)
    	
    	#  获取token
        async def get_jwt_token(self):
            jwt_res = await hash_tool().get_base64(self.header) + b'.' + await hash_tool().get_base64(
                self.payload) + b'.' + await hash_tool().get_base64(await self.jwt_sign())
            return jwt_res
    
    # 私钥
    secret = b"123456"
    jwt_header = json.dumps({'alg': 'HS256', 'typ': 'JWT'})
    jwt_payload = json.dumps({'exp': time.time() + 7200,  # Expiration Time 此token的过期时间的时间戳
                              'iss': 'couragesteak',  # (Issuer) Claim 指明此token的签发者
                              'iat': time.time(),  # (Issued At) Claim 指明此创建时间的时间戳
                              'data': {
                                  'username': 'charles'
                              }
                              })
    
    import asyncio
    
    async def func():
        print("========jwt结果 异步==========")
        j = Util_jwt(header=jwt_header, payload=jwt_payload, secret=secret)
        print(await j.get_jwt_token())
    
    asyncio.run(func())
    
    • 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

    3 🐮校验 jwt

    官网校验:https://jwt.io/

    在这里插入图片描述

    4 🐮js解析jwt

    <script src="https://cdn.jsdelivr.net/npm/js-base64@3.7.2/base64.min.js">script>
    
    • 1
    function jwt_parse(token) {
    	return Base64.atob(token.split(".")[1]);
    }
    
    • 1
    • 2
    • 3
    let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJcdTY3MDlcdTUyYzdcdTZjMTRcdTc2ODRcdTcyNWJcdTYzOTIiLCJpYXQiOjE2Njc0NTg5ODAsImV4cCI6MTY2ODA2Mzc4MCwiYXVkIjoid3d3LmNvdXJhZ2VzdGVhay5jb20iLCJkYXRhIjp7InVpZCI6MSwidXNlcm5hbWUiOiJjaGVhcmxlcyJ9fQ.4Xrf3Chpfu1qOnmDy7UQqJAt6dpvKBVxafvr7gdCwdk";
    let userinfo = jwt_parse(token)
    console.log(userinfo)
    
    • 1
    • 2
    • 3

    结果

    {
    	"iss": "有勇气的牛排",
    	"iat": 1667458980,
    	"exp": 1668063780,
    	"aud": "www.couragesteak.com",
    	"data": {
    		"uid": 1,
    		"username": "charles"
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    kong网关熔断插件
    后端防止重复点击
    【RtpSeqNumOnlyRefFinder】webrtc m98: ManageFrameInternal 的帧决策过程分析
    剑指offer常见题 - 二叉树问题(三)
    计算机中的数据表示
    论文阅读:BGE M3-Embedding——通过自知识提取实现多语言、多功能、多粒度的文本嵌入
    使用GPA和夜神模拟器实现K帧
    初级java必问必会的基础面试题
    笔记应用选择和知识管理
    批量将所有文件的磁盘路径名称提取到 txt 记事本文件中
  • 原文地址:https://blog.csdn.net/zx77588023/article/details/127447961