【Python】FastAPI:Token认证

FastAPI:Token认证

本教程通过 FastAPI 实现用户登录和基于 JWT(JSON Web Token) 的认证与授权,适合初学者到进阶用户。教程特别关注 DependsOAuth2PasswordBearer 等非基础操作的详细讲解,帮助你全面掌握相关技术。

环境准备

首先,确保安装必要的依赖库:

pip install fastapi uvicorn PyJWT

什么是 JWT

JWT (JSON Web Token) 是一种轻量级的认证机制,常用于客户端与服务器之间的通信。它主要包含三部分:

  • Header:算法与类型。
  • Payload:包含用户信息及声明。
  • Signature:用于校验数据完整性。

JWT 示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiJ1c2VyMSIsImV4cCI6MTY5MjMyMzAwMH0
.Wu6HB7pCDHgVvmD3_a8Ev9fGzY1Kc0FnVmCvO1Wl1qM

用户登录的基础实现

创建一个简单的用户登录接口,验证用户名和密码。首先实现模拟的用户数据库和基本的登录验证:

from fastapi import FastAPI, HTTPException
from fastapi.security import OAuth2PasswordRequestFormapp = FastAPI()# 模拟用户数据库
USERS_DB = {"admin": "password123","user": "mypassword"
}@app.post("/login")
async def login(form_data: OAuth2PasswordRequestForm):"""登录接口,验证用户名和密码是否匹配。"""username = form_data.usernamepassword = form_data.passwordif username not in USERS_DB or USERS_DB[username] != password:raise HTTPException(status_code=401, detail="用户名或密码错误")return {"message": f"欢迎回来,{username}!"}

启动服务:

uvicorn main:app --reload

访问 http://127.0.0.1:8000/docs,测试 /login 接口。

JWT 的生成与验证

引入 PyJWT 生成令牌。我们将为成功登录的用户生成一个包含身份信息和过期时间的 JWT。

import jwt
import datetimeSECRET_KEY = "your_secret_key"  # 替换为你的密钥
ALGORITHM = "HS256"            # 签名算法
TOKEN_EXPIRE_HOURS = 1         # 令牌有效时间(小时)def create_jwt(username: str) -> str:"""生成 JWT。"""payload = {"sub": username,  # 用户名"exp": datetime.datetime.utcnow() + datetime.timedelta(hours=TOKEN_EXPIRE_HOURS)  # 过期时间}return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)@app.post("/login")
async def login(form_data: OAuth2PasswordRequestForm):"""登录接口:验证用户名密码并返回 JWT。"""username = form_data.usernamepassword = form_data.passwordif username not in USERS_DB or USERS_DB[username] != password:raise HTTPException(status_code=401, detail="用户名或密码错误")token = create_jwt(username)return {"access_token": token, "token_type": "bearer"}

FastAPI 的认证工具

什么是 Depends

Depends 是 FastAPI 中的依赖注入工具,用于在路由中动态引入逻辑。例如,可以通过它获取登录用户的 Token,或者验证 Token 的合法性。

什么是 OAuth2PasswordBearer

OAuth2PasswordBearer 是 FastAPI 提供的一个工具,帮助我们解析 Bearer Token。它会从请求头的 Authorization 字段中提取 Token。

使用示例

from fastapi.security import OAuth2PasswordBeareroauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")  # 指定获取 Token 的登录端点
  • 当我们在路由中依赖 oauth2_scheme 时,它会自动解析 Token,并作为参数传递给路由函数。

实现受保护路由和 Token 验证

我们在这里验证 Token 的有效性,并返回用户信息。

from fastapi import Dependsdef decode_jwt(token: str):"""验证并解码 JWT。"""try:payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])return payloadexcept jwt.ExpiredSignatureError:raise HTTPException(status_code=401, detail="令牌已过期")except jwt.InvalidTokenError:raise HTTPException(status_code=401, detail="令牌无效")@app.get("/protected")
async def protected_route(token: str = Depends(oauth2_scheme)):"""受保护的路由,需提供有效 JWT。"""payload = decode_jwt(token)username = payload.get("sub")if not username:raise HTTPException(status_code=401, detail="令牌无效")return {"message": f"欢迎回来,{username}!这是一个受保护的路由。"}
  1. 使用 /login 接口获取 Token。
  2. 访问 /protected,并在 Authorization 请求头中添加 Bearer <your_token>

优化代码结构(解耦与扩展)

为了更好的维护和扩展,将用户管理和 JWT 逻辑拆分到独立模块中。

# services/user_service.py
class UserService:"""用户服务类:处理用户验证。"""def __init__(self):self.users_db = {"admin": "password123","user": "mypassword"}def authenticate(self, username: str, password: str) -> bool:"""验证用户名和密码是否匹配。"""return self.users_db.get(username) == password
import jwt
import datetime
from fastapi import HTTPExceptionclass JWTHandler:"""JWT 工具类:负责生成和验证 JWT。"""SECRET_KEY = "your_secret_key"ALGORITHM = "HS256"@staticmethoddef create_token(username: str) -> str:payload = {"sub": username,"exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)}return jwt.encode(payload, JWTHandler.SECRET_KEY, algorithm=JWTHandler.ALGORITHM)@staticmethoddef decode_token(token: str):try:return jwt.decode(token, JWTHandler.SECRET_KEY, algorithms=[JWTHandler.ALGORITHM])except jwt.ExpiredSignatureError:raise HTTPException(status_code=401, detail="令牌已过期")except jwt.InvalidTokenError:raise HTTPException(status_code=401, detail="令牌无效")
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from user_service import UserService
from jwt_handler import JWTHandlerapp = FastAPI()
user_service = UserService()
jwt_handler = JWTHandler()oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")@app.post("/login")
async def login(form_data:OAuth2PasswordRequestForm = Depends()):if not user_service.verify_user(form_data.username, form_data.password):raise HTTPException(status_code=401, detail="用户名或密码错误")token = jwt_handler.create_token(form_data.username)return {"access_token": token, "token_type": "bearer"}@app.get("/protected")
async def protected_route(token: str = Depends(oauth2_scheme)):payload = jwt_handler.decode_token(token)username = payload.get("sub")return {"message": f"欢迎回来,{username}!"}if __name__ == "__main__":import uvicornuvicorn.run(app, host="127.0.0.1", port=8000)

总结

通过本教程,你学会了:

  1. 基于 FastAPI 实现用户登录和 JWT Token 认证。
  2. 使用 DependsOAuth2PasswordBearer 实现认证逻辑。
  3. 解耦代码结构,提升可扩展性。

可以进一步扩展功能,比如引入数据库存储用户信息或添加刷新 Token 的机制。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第7章硬件测试-7.3 功能测试

7.3 功能测试 7.3.1 整机规格测试7.3.2 整机试装测试7.3.3 DFX测试 功能测试包括整机规格、整机试装和整机功能测试&#xff0c;是整机结构和业务相关的测试。 7.3.1 整机规格测试 整机规格测试包括尺寸、重量、温度、功耗等数据。这些测试数据与设计规格进行比对和校验&…

芯片之殇——“零日漏洞”(文后附高通64款存在漏洞的芯片型号)

芯片之殇——“零日漏洞”(文后附高通64款存在漏洞的芯片型号) 本期是平台君和您分享的第113期内容 前一段时间,高通公司(Qualcomm)发布安全警告称,提供的60多款芯片潜在严重的“零日漏洞”,芯片安全再一次暴露在大众视野。 那什么是“零日漏洞”?平台君从网上找了一段…

「Mac玩转仓颉内测版23」基础篇3 - 深入理解整数类型

本篇将详细讲解Cangjie中的整数类型&#xff0c;探讨整数的定义、操作、表示范围、进制表示、类型转换及应用场景&#xff0c;帮助开发者在Cangjie中灵活运用整数类型构建程序逻辑。 关键词 有符号整数与无符号整数表示范围与溢出进制表示类型转换字面量与操作 一、整数类型概…

如何恢復電腦IP地址的手動設置?

手動設置IP地址後&#xff0c;可能會遇到一些網路連接問題&#xff0c;或者需要恢復到之前的自動獲取狀態。這篇文章將詳細介紹如何恢復電腦的IP地址設置。 為什麼需要恢復IP地址設置&#xff1f; 網路連接問題&#xff1a;手動設置IP地址後&#xff0c;可能會導致與路由器或…

Python-简单病毒程序合集(一)

前言&#xff1a;简单又有趣的Python恶搞代码&#xff0c;往往能给我们枯燥无味的生活带来一点乐趣&#xff0c;激发我们对编程的最原始的热爱。那么话不多说&#xff0c;我们直接开始今天的编程之路。 编程思路&#xff1a;本次我们将会用到os,paltform,threading,ctypes,sys,…

跟我学C++中级篇——Design Patterns的通俗说法

一、设计模式 Design patterns&#xff0c;软件设计模式&#xff0c;它是什么&#xff1f;很多初学者会被这种高大上的东西给唬住。其实&#xff0c;所有的书籍上都说得很清楚&#xff0c;只是它们把这种说法说得很高大上而已。举个简单例子&#xff0c;在抖音上经常可以看到介…

Linux16 多路复用(二)

多路复用&#xff08;二&#xff09; 1. 多路复用 - poll功能函数原型关于 pollfd 结构体类型poll 代码框架一些示例代码poll相较于select优点poll的缺点 2. 多路复用 - epoll关于epoll的三个系统调用创建 - epoll_create控制 - epoll_ctl函数原型关于 epoll_event 结构体 等待…

数字化那点事:一文读懂物联网

一、物联网是什么&#xff1f; 物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;是指通过网络将各种物理设备连接起来&#xff0c;使它们可以互相通信并进行数据交换的技术系统。通过在物理对象中嵌入传感器、处理器、通信模块等硬件&#xff0c;IoT将“…

Jmeter的后置处理器(二)

5--JSR223 PostProcessor 功能特点 自定义后处理逻辑&#xff1a;使用脚本语言编写自定义的后处理逻辑。支持多种脚本语言&#xff1a;支持 Groovy、JavaScript、BeanShell 等脚本语言。动态参数传递&#xff1a;将提取的数据存储为变量&#xff0c;供后续请求使用。灵活性高…

非对称之美(贪心)

非对称之美(贪心) import java.util.*; public class Main{public static void main(String[] arg) {Scanner in new Scanner(System.in);char[] ch in.next().toCharArray(); int n ch.length; int flag 1;for(int i 1; i < n; i) {if(ch[i] ! ch[0]) {flag …

(11)(2.2) BLHeli32 and BLHeli_S ESCs(一)

文章目录 前言 1 参数说明 前言 BLHeli 固件和配置应用程序的开发是为了允许配置 ESC 并提供额外功能。带有此固件的 ESC 允许配置定时、电机方向、LED、电机驱动频率等。在尝试使用 BLHeli 之前&#xff0c;请按照 DShot 设置说明进行操作(DShot setup instructions)。 根据…

初始化列表和在构造函数体内赋值有什么区别?

1. 成员初始化方式 初始化列表&#xff1a; 在构造函数参数列表后面&#xff0c;使用冒号 : 进行初始化&#xff0c;成员变量在对象创建时直接初始化。语法&#xff1a;ClassName(Type1 arg1, Type2 arg2) : member1(arg1), member2(arg2) { }对于基本类型&#xff0c;使用初始…

Redis持久化、主从及哨兵架构详解

Redis持久化 RDB快照&#xff08;snapshot&#xff09; 在默认情况下&#xff0c;Redis将内存数据库快照保存在名字为dump.rdb的二进制文件中。 你可以对Redis进行设置&#xff0c;让它在“N秒内数据集至少有M个改动”这一条件被满足时&#xff0c;自动保存一次数据集。 比…

【Linux庖丁解牛】—Linux基本指令(下)!

目录 1、grep指令 2、zip/unzip指令 3、sz/rz指令 4、tar指令 ​编辑 5、scp指令 6、bc指令 7、uname –r指令 8、重要的几个热键 9、关机 10、完结撒花 1、grep指令 grep是文本过滤器&#xff0c;其作用是在指定的文件中过滤出包含你指定字符串的内容&#xff0c;…

Flutter踩坑记录(一)debug运行生成的项目,不能手动点击运行

问题 IOS14设备&#xff0c;切后台划掉&#xff0c;二次启动崩溃。 原因 IOS14以上 flutter 不支持debugger模式下的二次启动 。 要二次启动需要以release方式编译工程安装至手机。 操作步骤 清理项目&#xff1a;在命令行中运行flutter clean来清理之前的构建文件。重新构…

十六:请求与响应的上下文

在Web开发中,请求与响应是数据流动的核心。客户端发出请求,服务器返回响应,这一过程看似简单,但背后涉及复杂的上下文管理。理解并优化Web请求与响应的上下文,不仅能提升系统性能,还能改善用户体验。 请求与响应的基础 Web请求是由客户端(通常是浏览器或移动应用)向服…

联通光猫(烽火通信设备)改桥接教程

一、获得超级密码 1.打开telnet连接权限 http://192.168.1.1/telnet?enable1&key9070D3BECD70&#xff08;MAC地址&#xff09;2.连接光猫获取密码 telnet 192.168.1.1 用户名&#xff1a;admin 密码&#xff1a;Fh9070D3BECD70连接成功后 load_cli factory show admin_…

新华三H3CNE网络工程师认证—子接口技术

子接口&#xff08;subinterface&#xff09;是通过协议和技术将一个物理接口&#xff08;interface&#xff09;虚拟出来的多个逻辑接口。在VLAN虚拟局域网中&#xff0c;通常是一个物理接口对应一个 VLAN。在多个 VLAN 的网络上&#xff0c;无法使用单台路由器的一个物理接口…

基于Amazon Bedrock:一站式多模态数据处理新体验

目录 引言 关于Amazon Bedrock 基础模型体验 1、进入环境 2、发现模型及快速体验 3、打开 Amazon Bedrock 控制台 4、通过 Playgrounds 体验模型 &#xff08;1&#xff09;文本生成 &#xff08;2&#xff09;图片生成 关于资源清理 结束语 引言 在云计算和人工智能…

react native 安装好apk后无法打开

react native 打包好apk安装完成&#xff0c;没有打开app按钮&#xff0c; 在AndroidManifest.xml中 <intent-filter><action android:name"android.intent.action.MAIN" /><category android:name"android.intent.category.LAUNCHER" /&…