flask 之JWT认证实现

目录

1、JWT

1.1、JWT概述

1.2、token的生成

1.3、token校验

1.4、flask项目中实现JWT认证

1、JWT

1.1、JWT概述

JWT(JSON Web Token)是一种用于身份验证和授权的开放标准。它由三部分组成,分别是头部、负载和签名。

头部(Header)是一个 JSON 对象,描述了使用的算法和类型。它通常包含两个字段:算法(alg)和类型(typ)。

负载(Payload)也是一个 JSON 对象,用于存储用户的相关信息。它可以包含一些预定义的字段,如过期时间(exp)、发布时间(iat)等,也可以包含一些自定义字段。

签名(Signature)使用指定的算法对头部和负载进行加密,生成一段字符串。这个字符串可以用于验证数据的完整性。

1、传统的token认证流程

  1. 用户登录:用户输入用户名和密码,向服务器发送登录请求。
  2. 生成token:服务器验证用户名和密码的正确性,如果验证通过,则生成一个随机字符串作为token,并将这个token与用户ID等关键信息关联起来(例如,将token和用户ID作为键值对存储在Redis等缓存中)。
  3. 返回token:服务器将生成的token返回给客户端,客户端将token保存在cookie或localStorage中。
  4. 携带token:当客户端需要访问需要认证的接口时,会在请求头中携带这个token。
  5. 验证token:服务器在接收到请求后,会从请求头中提取token,并根据token在缓存中查找对应的用户信息。如果找到了对应的用户信息,则说明用户已经登录且token有效;否则,说明用户未登录或token已过期。

2、传统token认证流程和JWT的对比

  1. 存储方式:传统token方式需要将token保存在服务器端(如Redis),而JWT则将token的所有信息都包含在token本身中,无需在服务器端保存。
  2. 安全性:JWT通过签名机制来确保数据的完整性和防止篡改,而传统token方式则更依赖于服务器端的验证。
  3. 应用场景:JWT更适用于分布式系统或跨域请求的场景,而传统token方式则更适用于传统的Web应用。

1.2、token的生成

jwt的生成token格式如下,即:由 . 连接的三段字符串组成。

eyJhbGciOiJIUzI1NiIsInR5cCI6Imp3dCJ9.eyJ1c2VybmFtZSI6ImxqIiwiZXhwIjoxNzE2NzkyODI4fQ.WrT1XY8CC1vFo8tPpt0ZrDjje5ooD8hTOvIW42Z2WEo

1、生成规则如下:

  • token组成:将三段字符串通过 . 拼接起来就生成了jwt的token。
  • 第一段HEADER部分,固定包含算法和token类型,对此json进行base64url加密,这就是token的第一段。
headers = {
    'typ': 'jwt',
    'alg': 'HS256'
}
  • 第二段PAYLOAD部分,包含一些数据,对此PAYLOAD进行base64url加密,这就是token的第二段
payload = {
    'user_id':1,
    'username':'张三', 
    'role':'admin',
    'exp': "XXX"
    ...........
}
  • 第三段SIGNATURE部分,把前两段的base密文通过.拼接起来,然后对其进行HS256加密,再然后对hs256密文进行base64url加密,最终得到token的第三段。
base64url(
    HMACSHA256(
      base64UrlEncode(headers) + "." + base64UrlEncode(payload),
      secret # 秘钥加盐
    )
)

注意:base64url加密是先做base64加密,然后再把 - 替换 + _ 替换 / 。

2、代码实现:

  • 使用的库是:pyjwt模块。
  • 安装库:

pip install pyjwt

代码实现:

import jwt
import datetime

# 秘钥加盐
SALT = 'adasfasfgthfafklsaj?lkasld;)(hjasgbsvbfjh='

def create_token():
    # header
    headers = {
        'typ': 'jwt',
        'alg': 'HS256'
    }
    # payload
    payload = {
        'user_id': 1,  # 自定义用户ID
        'username': '张三',  # 自定义用户名
        'role': "admin", # 自定义角色
        'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=2)  # 过期时间(2个小时)
    }
    result = jwt.encode(headers=headers, payload=payload, key=SALT, algorithm=["HS256"])
    return result

if __name__ == '__main__':
    token = create_token()
    print(token)

1.3、token校验

获取token之后,会按照以下步骤(主要是进行超时和合法性校验)进行校验:

  • 将token分割成 header_segment、payload_segment、crypto_segment 三部分
  • 对第一部分header_segment进行base64url解密,得到header
  • 对第二部分payload_segment进行base64url解密,得到payload
  • 对第三部分crypto_segment进行base64url解密,得到signature后进行合法性校验。
    • 拼接前两段密文,即:signing_input
    • 从第一段明文中获取加密算法,默认:HS256
    • 使用 算法+盐 对signing_input 进行加密,将得到的结果和signature密文进行比较。

代码实现:

import jwt

# 秘钥加盐
SALT = 'adasfasfgthfafklsaj?lkasld;)(hjasgbsvbfjh='

def get_payload(token):
    try:
        # 校验token合法性和是否超时
        verified_payload = jwt.decode(jwt=token, key=SALT, verify=True, algorithms=["HS256"])
        return verified_payload
    except jwt.ExpiredSignatureError:
        print("token已过期")
    except jwt.DecodeError:
        print('token认证失败')
    except jwt.InvalidTokenError:
        print('非法的token')

if __name__ == '__main__':
    token = "eyJhbGciOiJIUzI1NiIsInR5cCI6Imp3dCJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6Ilx1NWYyMFx1NGUwOSIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxNzQwMDIwMn0.iXqTAykKdA8ln0WMCsdhcc3Je0l4qOvYoxctkjEmhHs"
    payload = get_payload(token)
    print(payload)

1.4、flask项目中实现JWT认证

项目的目录结构如下:

1、app.py文件

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import base64
from flask import Flask, request, jsonify, g
from utils.jwt_auth import create_token, check_token

app = Flask(__name__)

# 通过url传递token
# 每一个请求前都进行token的验证
# @app.before_request
# def jwt_query_params_auth():
#     if request.path == '/login/':
#         return
#     token = request.args.get('token')
#     result = check_token(token)
#     if not result['status']:
#         return jsonify(result)
#     g.user_info = result['info']


# 通过Authorization请求头传递token


@app.before_request
def jwt_authorization_auth():
    if request.path == '/login/':
        return
    # 在实际项目中Authorization的组成一般是: Bearer toekn
    authorization = request.headers.get('Authorization', '')
    token = ""
    # 对head进行解密
    if authorization:
        # 获取token信息
        token = authorization.split(" ")[1]
        # 获取token中的header加密部分
        encoded_header = token.split(".")[0]
        # 注意:我们需要替换字符并确保字符串长度是 4 的倍数
        padded = encoded_header + '=' * (-len(encoded_header) % 4)
        # 对header进行base64url解密
        header = base64.urlsafe_b64decode(padded.replace('-', '+').replace('_', '/')).decode('utf-8')
        print(header)

    result = check_token(token)
    if not result['status']:
        return jsonify(result)
    g.user_info = result['info']



@app.route('/login/', methods=['POST'])
def login():
    user = request.form.get('username')
    pwd = request.form.get('password')
    print(user)
    # 检测用户和密码是否正确,此处可以在数据进行校验。
    if user == '张三' and pwd == '123456':
        # 用户名和密码正确,给用户生成token并返回
        token = create_token({'user_id':1, 'username':'张三', 'role':'admin'})
        return jsonify({'status': True, 'token': token})
    return jsonify({'status': False, 'error': '用户名或密码错误!'})


@app.route('/info/')
def order():
    print(g.user_info)
    return jsonify(g.user_info)


if __name__ == '__main__':
    app.run(debug=True)

2、jwt_auth.py文件

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import jwt
import datetime

# 秘钥加盐
SALT = 'adasfasfgthfafklsaj?lkasld;)(hjasgbsvbfjh='

def create_token(payload, timeout=60):
    """
    :function: 创建token
    :param payload:  例如:{'user_id':1,'username':'张三', 'role':'admin'}用户信息
    :param timeout: token的过期时间,默认60分钟
    :return:
    """
    headers = {
        'typ': 'jwt',
        'alg': 'HS256'
    }
    payload['exp'] = datetime.datetime.utcnow() + datetime.timedelta(minutes=timeout)
    result = jwt.encode(headers=headers, payload=payload, key=SALT, algorithm="HS256")
    return result


def check_token(token):
    """
    :function: 检验token的合法性和是否过期
    :param token: 用户token信息
    :return: 返回检验结果
    """
    result = {'status': False, 'info': None, 'msg': None}
    try:
        print(token)
        verified_payload = jwt.decode(jwt=token, key=SALT, verify=True, algorithms=["HS256"])
        result['status'] = True
        result['info'] = verified_payload
    except jwt.ExpiredSignatureError:
        result['msg'] = 'token已失效'
    except jwt.DecodeError:
        result['msg'] = 'token认证失败'
    except jwt.InvalidTokenError:
        result['msg'] = '非法的token'
    return result

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/675140.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

24、Linux网络端口

Linux网络端口 1、查看网络接口信息ifconfig ens33 eth0 文件 ifconfig 当前设备正在工作的网卡,启动的设备。 ifconfig -a 查看所有的网络设备。 ifconfig ens33 查看指定网卡设备。 ifconfig ens33 up/down 对指定网卡设备进行开关 基于物理网卡设备虚拟的…

搭建 3D 智慧农场可视化

运用图扑自主研发的 HT 产品,全程零代码搭建 3D 轻量化 Low Poly 风格的智慧农场可视化解决方案,无缝融合 2D、3D 技术,1:1 还原农场的区域规划,展开对农作物间的网格化管理。

真国色码上赞,科技流量双剑合璧,商家获客新纪元开启

在数字化浪潮汹涌的今天,真国色研发团队依托红玉房网络科技公司的雄厚实力,凭借科技领先的核心竞争力,推出了创新性的商家曝光引流工具——码上赞。这款工具借助微信支付与视频号已有功能,为实体商家提供了一种全新的引流获客方式,实现了科技与商业的完美融合。 科技领先,流量黑…

MATLAB format

在MATLAB中,format 是一个函数,用于控制命令窗口中数值的显示格式。这个函数可以设置数值的精度、显示的位数等。以下是一些常用的 format 命令: format long:以默认的长格式显示数值,通常显示15位有效数字。format s…

图像处理之基于标记的分水岭算法(C++)

图像处理之基于标记的分水岭算法(C) 文章目录 图像处理之基于标记的分水岭算法(C)前言一、基于标记点的分水岭算法应用1.实现步骤:2.代码实现 总结 前言 传统分水岭算法存在过分割的不足,OpenCV提供了一种…

CTFHUB-密码口令-弱口令

目录 题干介绍 密码字典 找flag过程 尾声 题干介绍 通常认为容易被别人(他们有可能对你很了解)猜测到或被破解工具破解的口令均为弱口令。 密码字典 下载地址:GitHub - NepoloHebo/Commonly-used-weak-password-dictionary: 常用弱密码字…

川北医学院与爱尔眼科医院集团签署战略合作协议共谋医学发展新篇章

为深入贯彻落实党的二十大精神,统筹校、企、医、政多方资源,服务“健康中国”战略,推动眼健康产业发展,打造国家及区域级眼科医学中心,2024年5月31日,川北医学院与爱尔眼科医院集团在成都举行战略合作协议签…

腾讯云 TDMQ for Apache Pulsar 多地区高可用容灾实践

作者介绍 林宇强 腾讯云高级工程师 专注于消息队列、API网关、微服务、数据同步等 PaaS 领域。有多年的开发和维护经验,目前在腾讯云从事 TDMQ Pulsar 商业化产品方向的研发工作。 导语 本文将从四个维度,深入剖析 Pulsar 在多可用区高可用领域的容…

单实例11.2.0.4迁移到11.2.0.4RAC_使用rman异机恢复

保命法则:先备份再操作,磁盘空间紧张无法备份就让满足,给自己留退路。 场景说明: 1.本文档的环境为同平台、不同版本(操作系统版本可以不同,数据库版本相同),源机器和目标机器部分…

QML信号连接到c++的槽函数(五)

文章目录 前言一、QML Signal and Handler Event System二、QML信号连接到c++的槽函数代码实例1. 创建一个QML 工程2. 用C++ 实现一个QML Types3. 代码实例4. 运行结果总结参考资料前言 本文主要介绍,如何将QML 中的信号连接到C++ 中的槽函数 软硬件环境: 硬件:PC 软件:wi…

MDK5.10 安装手册

1.MDK5.10 安装 打开开发板光盘: 6 ,软件资料 \ 软件 \MDK5 ,双击 mdk_510.exe ,进行安装。这里我们 将其安装到 D 盘, MDK5.10 文件夹下,需要设置安装路径,如图 1.1 所示: …

上传图片并显示#Vue3#后端接口数据

上传图片并显示#Vue3#后端接口数据 效果&#xff1a; 上传并显示图片 代码&#xff1a; <!-- 上传图片并显示 --> <template><!-- 上传图片start --><div><el-form><el-form-item><el-uploadmultipleclass"avatar-uploader&quo…

独立游戏开发的 6 个步骤

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

计算机网络⑩ —— Linux系统如何收发网络包

转载于小林coding&#xff1a;https://www.xiaolincoding.com/network/1_base/how_os_deal_network_package.html 1. OSI七层模型 应用层&#xff0c;负责给应用程序提供统一的接口&#xff1b;表示层&#xff0c;负责把数据转换成兼容另一个系统能识别的格式&#xff1b;会话…

【Python】 如何将 datetime 转换为 date?

基本原理 在 Python 中&#xff0c;我们经常需要处理日期和时间。datetime 模块提供了丰富的功能来处理日期和时间。datetime 类型和 date 类型是 datetime 模块中的两个不同的类型。datetime 类型包含了日期和时间的信息&#xff0c;而 date 类型只包含日期信息。 当你需要将…

运筹学_7.博弈论(对策略)

文章目录 引言7.1 博弈论(对策论)的基本概念对策论有三个基本假设对策论的三个要素零和对策二人有限零和对策 7.2 矩阵对策矩阵对策数学模型 7.3 最优纯策略基本定理和性质最优纯策略基本定理最优纯策略基本性质 7.4 混合策略定义和性质混合策略的定义混合策略的性质 7.5 矩阵对…

德国RS SMA100A原装二手sma100a信号发生器6G

罗德与施瓦茨 SMA100A信号发生器&#xff0c;9 kHz 至 3 GHz 或 6 GHz R&S SMA100A 提供信号质量、速度和灵活性。R&S SMA100A 是一款高级模拟发生器&#xff0c;因其出色的特性而树立了标准。 它结合了卓越的信号质量和极高的设置速度。无论是在开发、生产、服务还是维…

GSEA的算法只考虑排序吗

其实这个问题很好回答&#xff0c;只需要运行如下代码&#xff0c;如下的基因列表是顺序是完全相同&#xff0c;并且我们只是做了最基础的变换 library(clusterProfiler) library(org.Hs.eg.db)data(geneList, package"DOSE")ego1 <- gseGO(geneList geneLi…

企业在现代市场中的战略:通过数据可视化提升财务决策

新时代&#xff0c;财务规划团队不仅仅是企业内部的一个部门&#xff0c;更是帮助企业做出明智决策和设定战略目标的中坚力量。在当今瞬息万变的商业环境中&#xff0c;财务专业人士需要具备应对挑战并引导企业走向成功的角色职能。企业领导者时常面临着数据压力&#xff0c;需…

如何快速部署上线项目

CSDN 的小伙伴们&#xff0c;大家好呀&#xff0c;我是苍何。 今天在群里面看到有小伙伴反馈说&#xff0c;面试的时候一被问到简历中的项目还没上线&#xff0c;就不继续问了&#xff0c;感觉挺奇葩的&#xff0c;要知道就校招来说&#xff0c;项目本身大部分都是练手的项目&…