如何在Flask应用程序中使用JSON Web Tokens进行安全认证

密码、信用卡信息、个人识别号码(PIN)——这些都是用于授权和认证的关键资产。这意味着它们需要受到未经授权的用户的保护。

作为开发者,我们的任务是保护这些敏感信息,并且在我们的应用程序中实施强大的安全措施非常重要。

现在,有许多认证机制可用于保护数据,如OAuth、OpenID Connect和JSON Web Tokens(JWTs)。

在本文中,我将向您展示如何通过在Flask应用程序中集成基于JWT的身份验证来使用JWTs来保护API中的信息。

以下是本文的内容:

  • 什么是JSON Web Token?
  • JWTs如何工作?
  • 如何使用JSON Web Tokens来认证Flask应用程序
    1. 安装依赖项
    2. 创建数据库和用户模型
    3. 配置应用程序以进行JWT身份验证
    4. 创建受保护的路由
    5. 创建登录功能
  • 结论

(本文视频讲解:java567.com)

先决条件

要按照本教程进行操作,您需要:

  • 理解HTTP方法
  • 理解如何在Flask中创建API
  • VS Code(或其他类似的)编辑器
  • 一个终端

什么是JSON Web Token?

JSON Web Tokens,简称JWTs,是一种用于在客户端和服务器之间安全传输信息的认证机制,使用JSON格式。

这些信息可以被验证和信任,因为它使用HMAC算法或使用RSA或ECDSA的公钥/私钥对进行数字签名。

令牌被编码为三部分,每部分由一个句点分隔,如下所示:

Header.Payload.Signature
  • **Header:**这定义了令牌的类型(JWT)和使用的签名算法。
  • **Payload:**这承载着用户特定的数据,如用户ID、用户名、角色和您想要包含的任何其他声明。此有效载荷被Base64编码以获得最大的安全性。
  • **Signature:**这是头部、有效载荷和服务器的秘密密钥的散列组合。它确保了令牌的完整性,并且任何对令牌的修改都将被检测到。

JWTs如何工作?

要理解JWTs如何工作,您需要知道令牌的作用。JWTs不是为了隐藏数据,而是为了确保正在发送的数据得到了认证。这就是为什么JWT被签名和编码,而不是加密。

JWT充当了从客户端向服务器传输数据的无状态手段。这意味着它不会在浏览器中存储任何会话对象,因此浏览器不会在请求之间保持会话状态。

而是,JWT使用一个令牌,在每次发出请求时都以请求头的形式发送。此令牌确认发送的令牌经过了认证,并允许访问该请求。

让我们看看这是如何发生的:

  1. 用户尝试登录并发送用户名和密码以由服务器验证。
  2. 验证函数执行检查,看看数据库中是否有匹配项。
  3. 一旦用户使用其信息(有效载荷)成功认证(登录),服务器就会生成一个JWT,并使用秘密密钥对其进行签名。
  4. 生成的JWT随每个请求头一起作为承载令牌发送,以检查用户是否被授权进行该请求。

如何在Flask应用程序中使用JSON Web Tokens进行身份验证

为了演示如何在Flask中实现JWT身份验证,我们将创建一个简单的应用程序,该应用程序使用JWT来处理登录功能和访问受保护的路由。

1. 安装依赖项

运行以下命令以安装我们需要的依赖项:

pip install flask flask-bcrypt Flask-JWT-Extended

接下来,请确保您导入依赖项并使用以下代码初始化您的Flask应用程序:

from flask import Flask, jsonify, session, request, redirect, url_for
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity, get_jwt


app = Flask(__name__)

////在这里编写主要代码


if __name__ == "__main__":
    with app.app_context():
        app.run(debug=True)

2. 创建数据库和用户模型

为此,我们将使用SQL-Alchemy,它是一个Python SQL工具包,使在Python脚本中使用SQL变得不那么复杂。

要在应用程序中设置SQL Alchemy,请按照以下步骤操作:

首先,打开您的终端或命令提示符,并输入以下命令:

pip install sqlalchemy

此命令会在您的Python环境中安装SQLAlchemy,使其在项目目录中可用。

接下来,配置您的应用程序以使用您首选的数据库管理系统(DBMS)。本教程将使用SQlite3 DBMS,因为它不需要单独的服务器:

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'

此代码片段指示Flask-SQLAlchemy在您的项目目录中创建并使用site.db文件作为应用程序的SQLite数据库。

然后在您的应用程序中初始化数据库:

db = SQLAlchemy(app)

这个数据库的实例充当应用程序和数据库之间的桥梁。

现在创建User模型,我们将在本教程中存储用户的详细信息:

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    password = db.Column(db.String(80), nullable=False)
    is_active = db.Column(db.Boolean(), default=True)
    cart = db.Column(JSON, nullable=True, default=list)  # Make cart nullable

    # Define the relationship between User and CartProducts
    cart_products = relationship('CartProducts', backref="user", lazy="dynamic")
    # Define the relationship between User and Wishlists
    wishlists = db.relationship('Wishlists', backref='user', lazy=True)

    def __repr__(self):
        return f'<User {self.username}>'

**注意:**您可以使用相同的语法创建其他模型,以表示应用程序中的不同数据实体。

3. 配置应用程序以进行JWT身份验证

要在您的Flask应用程序中实现JWT身份验证,请导入必要的库并使用以下代码设置适当的配置:

from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import JWTManager, create_access_token, jwt_required

app = Flask(__name__)

# 配置
app.config['SECRET_KEY'] = 'your_strong_secret_key'
app.config["JWT_SECRET_KEY"] = 'your_jwt_secret_key'
app.config['JWT_TOKEN_LOCATION'] = ['headers']

# 数据库初始化
db = SQLAlchemy(app)

# JWT初始化
jwt = JWTManager(app)

# 应用程序的其他代码(路由等)

此代码片段导入了我们应用程序所需的以下组件:

  • app.config[‘SECRET_KEY’] 设置Flask应用程序的秘密密钥,用于安全地签名会话cookie和其他安全相关需求。
  • app.config[‘JWT_SECRET_KEY’] 设置用于对Flask-JWT操作中的JWT进行编码和解码的秘密密钥。
  • app.config[‘JWT_TOKEN_LOCATION’] 指定应用程序应在何处查找JWT。在这里,它设置为在HTTP标头中查找。

一旦我们设置了这些,我们就可以创建我们打算保护的端点和路由了。

4. 创建受保护的路由

受保护的路由是我们打算对未经授权的用户隐藏的页面。

例如,假设我们试图进入一个只允许社会成员进入的场所。但是,一名保安正在阻止“未经授权的用户”像我们这样进入场所。在这种情况下,我们是应用程序的用户,场所是我们正在保护的URL,保安是一个**@jwt_required**装饰器。

**@jwt_required**装饰器用于保护需要身份验证的特定路由。此装饰器将在允许访问页面之前确认请求标头中是否有JWT访问令牌:

@app.route('/get_name', methods=['GET'])
@jwt_required()
def get_name():
    # 从JWT中提取用户ID
    user_id = get_jwt_identity()
    user = User.query.filter_by(id=user_id).first()

    # 检查用户是否存在
    if user:
        return jsonify({'message': 'User found', 'name': user.name})
    else:
        return jsonify({'message': 'User not found'}), 404

在此代码片段中,我们创建了一个函数,在身份验证后返回用户的名称。如果缺少令牌、令牌无效或过期,请求将被拒绝,并且通常服务器将返回HTTP 401 Unauthorized状态。

5. 创建登录页面

在此端点中,我们将创建一个函数,该函数从客户端请求(例如,表单数据)接受用户名和密码凭据,并将从用户获取的凭据与数据库中的用户数据进行比较。如果匹配成功,将生成包含用户信息的JWT访问令牌。

@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data['username']
    password = data['password']
    print('Received data:', username , password)

    user = User.query.filter_by(username=username).first()

    if user and bcrypt.check_password_hash(user.password, password):
        access_token = create_access_token(identity=user.id)
        return jsonify({'message': 'Login Success', 'access_token': access_token})
    else:
        return jsonify({'message': 'Login Failed'}), 401

在此示例中,当收到POST请求时,函数使用bcrypt对用户的凭据与数据库进行安全密码验证。如果凭据有效,服务器将为用户生成JWT,允许他们访问受保护的路由。

这是一个示例React表单,将POST请求发送到登录端点:

import React from "react";
import axios from "axios";
import { useState } from "react";
import Footer from "./Footer";
// import "./Login.css";

function Login() {
  const [password, setPassword] = useState("");
  const [username, setUsername] = useState("");

  const handleLogin = async (event) => {
    event.preventDefault();
    const data = {
      username: username,
      Password: password,
    };

    try {
      const response = await axios.post("http://localhost:5000/login", {
        username,
        password,
      });
      localStorage.setItem("access_token", response.data.access_token);
      // Redirect to protected route
      alert("Login successful");
    } catch (error) {
      console.error(error);
      // Display error message to user
    }
  };

  const handleUsernameChange = (event) => {
    setUsername(event.target.value);
  };

  const handlePasswordChange = (event) => {
    setPassword(event.target.value);
  };

  return (
    <div >
      
          <form method="post" >
              <input
                type="text"
                id=""
                placeholder="Username"
                name="username"
                required
                value={username}
                onChange={handleUsernameChange}
              />
              <input
                type="text"
                id=""
                placeholder="Your email"
              />
              <input
                type="password"
                required
                placeholder="Your Password"
                name="password"
                value={password}
                onChange={handlePasswordChange}
              />
          </form>
          <button type="submit" onClick={handleLogin}>
            Log In
          </button>
       
    </div>
  );

}

export default Login;

在此React组件中,我们提供了一个登录表单,该表单使用Axios将POST请求发送到登录端点。它使用React的useState钩子管理用户名和密码输入,并在提交表单后提交这些值。

如果登录成功,它会将JWT存储在本地存储中。这使得客户端应用程序在向服务器发出经过身份验证的请求时可以轻松地检索令牌。

jwtDemo-1

结论

在本文中,我们学习了如何在Flask中使用JSON Web Tokens来保护API。我们介绍了JWT的基础知识,它们的工作原理,并提供了一个逐步的过程来实现这种身份验证方法。这包括安装必要的依赖项,创建用户模型和保护路由等内容。

您可以在此基础上构建更多功能,例如添加刷新令牌、与第三方OAuth提供程序集成或处理更复杂的用户权限。

(本文视频讲解:java567.com)

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

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

相关文章

24.4.28(板刷dp,拓扑判环,区间dp+容斥算回文串总数)

星期一&#xff1a; 昨晚cf又掉分&#xff0c;小掉不算掉 补ABC350 D atc传送门 思路&#xff1a;对每个连通块&#xff0c;使其成为一个完全图&#xff0c;完全图的边数为 n*(n-1)/2 , 答案加上每个连通块成为完全图后的…

Anti-BAFF (mouse), mAb (blocking) (Sandy-2)

Adipogen开发了可以用于体内实验作为阻断剂的小鼠的抗BAFF单克隆抗体&#xff0c;为肿瘤学、免疫学、免疫治疗、自身免疫性疾病&#xff0c;小鼠模型体内实验等研究领域的实验者们对BAFF通路的研究提供了强有力的工具。 。 B细胞激活因子&#xff08;BAFF&#xff09;又称肿瘤坏…

通过Linux命令查看GPU使用情况以及各种参数解释

查看Linux服务器GPU使用情况&#xff0c;以及各种参数解释 查看GPU使用情况参数解释 查看GPU使用情况 静态查看命令 只能看当前这一时刻gpu的各项数据 nvidia-smi动态查看命令 顾名思义&#xff0c;可以实时监测gpu的各项数据。 watch -n 1 nvidia-smi参数解释 解释相关参…

国外大学和留学申请者之间的AI博弈

自推出 ChatGPT 以来&#xff0c;大学招生官一直在为生成式人工智能对大学申请文书所带来的影响而绞尽脑汁&#xff0c;应对这一变化的最直接的结果是&#xff0c;越来越多负责审阅申请资料的工作也被人工智能所取代。 用AI打败AI&#xff1f; 申请文书的替代方案 如今&#…

有趣的大模型之我见 | Llama AI Model

Llama 开源吗&#xff1f; 我在写《有趣的大模型之我见 | Mistral 7B 和 Mixtral 8x7B》时曾犹豫&#xff0c;在开源这个事儿上&#xff0c;到底哪个大模型算鼻祖&#xff1f;2023 年 7 月 18 日&#xff0c;Meta 推出了最受欢迎的大型语言模型&#xff08;LLM&#xff09;的第…

基于 Spring Boot 博客系统开发(二)

基于 Spring Boot 博客系统开发&#xff08;二&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握SprIng Boot 框架及相关技术的使用。&#x1f33f;&#x1f33f;&#x1f33f; 基于 Spring Boot 博客系统开发&#xff08;一&#xff09;&#x1f4…

git出错、文件无法删除、文件无法访问、文件或目录损坏且无法读取 等相关问题处理

一、错误历程与解决方案 1. 在用idea时&#xff0c;突然出现 部分git的命令无法使用&#xff0c;提示错误 2. 尝试删除项目文件夹&#xff0c;重新从git拉取代码 3.发现无法删除文件夹&#xff0c;删除操作没有任何反应&#xff0c;但是可以对文件夹重命名。 4.重新clone g…

Find My无人机|苹果Find My技术与无人机结合,智能防丢,全球定位

无人机是利用无线电遥控设备和自备的程序控制装置操纵的不载人飞机&#xff0c;或者由车载计算机完全地或间歇地自主地操作。无人机按应用领域&#xff0c;可分为军用与民用。军用方面&#xff0c;无人机分为侦察机和靶机。民用方面&#xff0c;无人机行业应用&#xff0c;是无…

ArcGIS Pro3.0软件破解版安装教程

软件名称&#xff1a;ArcGIS Pro 3.0 安装环境&#xff1a;Windows 软件大小&#xff1a;7.3GB 硬件要求&#xff1a;CPU2GHz&#xff0c;内存4G(或更高) 百度云下载链接 &#xff1a; https://pan.baidu.com/s/1CXy1MSwdQXdVnJoV2X422A 提 取 码 &#xff1a;r0w1 教学内…

【多维动态规划】Leetcode 64. 最小路径和【中等】

最小路径和 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 示例 1&#xff1a; 输入&#xff1a;grid [[1,3,1],[1,5,1],[4,2,1]] 输出…

HotSpot JVM 为啥要叫做 HotSpot JVM?

1. Java与编译相关的三个概念&#xff1a; 首先了解三个概念 前端编译解释执行编译执行 ▌1.1、前端编译 编译器&#xff08;javac&#xff09;将源文件&#xff08;.java&#xff09;编译成java字节码文件&#xff08;.class&#xff09;的步骤是前端编译。 ▌1.2、解释执…

日本极致产品力 | 源自内蒙古,日本99.7%的人都喝过都百年畅销饮料

​《极致产品力》日本深度研学是一个顾问式课程,可以帮助企业找产品、找方向、找方法,在日本终端市场考察中洞悉热销产品背后的成功逻辑,了解最新最前沿的产品趋势和机会。结合日本消费趋势中国转化的众多经验,从品牌、包装、卖点、技术和生产工艺等多方面寻找中国市场的解决方…

【Linux系统化学习】死锁 | 线程同步

目录 死锁 死锁的必要条件 避免死锁 线程同步 条件变量 同步概念和竞态条件 条件变量接口 创建和初始化条件变量 等待条件满足 唤醒等待 毁条件变量 为什么 pthread_cond_wait 需要互斥量? 条件变量使用规范 等待条件代码 给条件发送信号代码 死锁 死锁是指在一…

Agent AI智能体在未来,一定与你我密不可分

随着Agent AI智能体的逐渐成熟&#xff0c;人工智能应用的不断深入与拓展&#xff0c;相信在不久的将来&#xff0c;他与你我的生活一定是密不可分的。 目录 ​编辑 1 Agent AI智能体是什么&#xff1f; 2 Agent AI在语言处理方面的能力 2.1 情感分析示例 2.2 文本分类任…

开发总结-Dao层(Mapper层)

Mybatis-plus新用法 VehicleBO one vehicleService.getOne(Wrappers.<VehicleBO>lambdaQuery().eq(VehicleBO::getVin, reqVo.getVin()));boolean b bizAccountApplyService.remove(Wrappers.<BizAccountApplyBO>lambdaQuery().eq(BizAccountApplyBO::getId, 14…

第一阶段--Day2--信息安全法律法规、网络安全相关标准

目录 1. 针对信息安全的规定 2. 网络安全相关标准 1. 针对信息安全的规定 《中华人民共和国计算机信息系统安全保护条例》1994年2月18日颁布并实施 中华人民共和国计算机信息系统安全保护条例__增刊20111国务院公报_中国政府网 《中华人民共和国国际联网安全保护管理…

纯血鸿蒙APP实战开发——Navigation实现多设备适配案例

介绍 在应用开发时&#xff0c;一个应用需要适配多终端的设备&#xff0c;使用Navigation的mode属性来实现一套代码&#xff0c;多终端适配。 效果图预览 使用说明 将程序运行在折叠屏手机或者平板上观看适配效果。 实现思路 本例涉及的关键特性和实现方案如下&#xff1a…

Android 音视频播放器 Demo(一)—— 视频解码与渲染

本篇作为 Android 音视频实战系列的第二篇文章&#xff0c;主要介绍视频解码与渲染过程。本系列文章目录如下&#xff1a; Android 音视频基础知识 Android 音视频播放器 Demo&#xff08;一&#xff09;—— 视频解码与渲染 Android 音视频播放器 Demo&#xff08;二&#xff…

金属冶炼及压延加工制造数字孪生可视化平台,推进行业数字化转型

金属冶炼及压延加工制造数字孪生可视化平台&#xff0c;推进行业数字化转型。随着科技的不断进步和工业的快速发展&#xff0c;金属冶炼及压延加工行业正面临着前所未有的挑战和机遇&#xff0c;数字化转型成为了行业发展的必然趋势。在这个过程中&#xff0c;数字孪生可视化平…

【前端热门框架【vue框架】】——条件渲染和列表渲染的学习的秒杀方式

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;程序员-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;v…