赞
踩
密码、信用卡信息、个人识别号码(PIN)——这些都是用于授权和认证的关键资产。这意味着它们需要受到未经授权的用户的保护。
作为开发者,我们的任务是保护这些敏感信息,并且在我们的应用程序中实施强大的安全措施非常重要。
现在,有许多认证机制可用于保护数据,如OAuth、OpenID Connect和JSON Web Tokens(JWTs)。
在本文中,我将向您展示如何通过在Flask应用程序中集成基于JWT的身份验证来使用JWTs来保护API中的信息。
以下是本文的内容:
(本文视频讲解:java567.com)
要按照本教程进行操作,您需要:
JSON Web Tokens,简称JWTs,是一种用于在客户端和服务器之间安全传输信息的认证机制,使用JSON格式。
这些信息可以被验证和信任,因为它使用HMAC算法或使用RSA或ECDSA的公钥/私钥对进行数字签名。
令牌被编码为三部分,每部分由一个句点分隔,如下所示:
Header.Payload.Signature
要理解JWTs如何工作,您需要知道令牌的作用。JWTs不是为了隐藏数据,而是为了确保正在发送的数据得到了认证。这就是为什么JWT被签名和编码,而不是加密。
JWT充当了从客户端向服务器传输数据的无状态手段。这意味着它不会在浏览器中存储任何会话对象,因此浏览器不会在请求之间保持会话状态。
而是,JWT使用一个令牌,在每次发出请求时都以请求头的形式发送。此令牌确认发送的令牌经过了认证,并允许访问该请求。
让我们看看这是如何发生的:
为了演示如何在Flask中实现JWT身份验证,我们将创建一个简单的应用程序,该应用程序使用JWT来处理登录功能和访问受保护的路由。
运行以下命令以安装我们需要的依赖项:
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)
为此,我们将使用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}>'
**注意:**您可以使用相同的语法创建其他模型,以表示应用程序中的不同数据实体。
要在您的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) # 应用程序的其他代码(路由等)
此代码片段导入了我们应用程序所需的以下组件:
一旦我们设置了这些,我们就可以创建我们打算保护的端点和路由了。
受保护的路由是我们打算对未经授权的用户隐藏的页面。
例如,假设我们试图进入一个只允许社会成员进入的场所。但是,一名保安正在阻止“未经授权的用户”像我们这样进入场所。在这种情况下,我们是应用程序的用户,场所是我们正在保护的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状态。
在此端点中,我们将创建一个函数,该函数从客户端请求(例如,表单数据)接受用户名和密码凭据,并将从用户获取的凭据与数据库中的用户数据进行比较。如果匹配成功,将生成包含用户信息的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存储在本地存储中。这使得客户端应用程序在向服务器发出经过身份验证的请求时可以轻松地检索令牌。
在本文中,我们学习了如何在Flask中使用JSON Web Tokens来保护API。我们介绍了JWT的基础知识,它们的工作原理,并提供了一个逐步的过程来实现这种身份验证方法。这包括安装必要的依赖项,创建用户模型和保护路由等内容。
您可以在此基础上构建更多功能,例如添加刷新令牌、与第三方OAuth提供程序集成或处理更复杂的用户权限。
(本文视频讲解:java567.com)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。