FastAPI 实战:从零实现一个可执行的 JWT 登录认证接口
一、前言在 Web 后端开发中登录认证几乎是每个项目都会遇到的基础功能。传统 Session 方案需要服务端保存用户状态而 JWT 更适合前后端分离项目。本文将使用 FastAPI 实现一个完整、可执行的 JWT 登录认证流程包括安装依赖编写登录接口生成 JWT Token校验 JWT Token获取当前登录用户访问需要登录才能使用的接口本文示例代码可以直接复制运行。二、JWT 是什么JWT全称 JSON Web Token是一种用于在客户端和服务端之间安全传递身份信息的 Token 格式。一个 JWT 通常由三部分组成Header.Payload.Signature其中Header声明 Token 类型和签名算法Payload保存用户相关信息例如用户 ID、用户名、过期时间Signature签名用于防止 Token 被篡改用户登录成功后服务端会生成 JWT 并返回给客户端。客户端后续请求接口时在请求头中携带这个 Token服务端验证通过后即可识别当前用户身份。三、准备环境本文示例环境Python 3.10 FastAPI Uvicorn python-jose passlib安装依赖python -m pip install fastapi uvicorn python-jose passlib[bcrypt] python-multipart说明fastapi Web 框架 uvicorn ASGI 服务 python-jose 生成和解析 JWT passlib[bcrypt] 密码加密与校验 python-multipart 支持表单登录项目结构fastapi-jwt-demo/ └── main.py四、完整代码创建main.py文件写入以下代码from datetime import datetime, timedelta from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jose import JWTError, jwt from passlib.context import CryptContext from pydantic import BaseModel app FastAPI() SECRET_KEY change-this-secret-key ALGORITHM HS256 ACCESS_TOKEN_EXPIRE_MINUTES 30 pwd_context CryptContext(schemes[bcrypt], deprecatedauto) oauth2_scheme OAuth2PasswordBearer(tokenUrl/login) fake_users_db { admin: { username: admin, hashed_password: pwd_context.hash(123456), disabled: False, } } class TokenResponse(BaseModel): access_token: str token_type: str class UserInfo(BaseModel): username: str disabled: bool False def verify_password(plain_password: str, hashed_password: str) - bool: return pwd_context.verify(plain_password, hashed_password) def authenticate_user(username: str, password: str): user fake_users_db.get(username) if not user: return None if not verify_password(password, user[hashed_password]): return None return UserInfo(usernameuser[username], disableduser[disabled]) def create_access_token(data: dict, expires_delta: timedelta): to_encode data.copy() expire datetime.utcnow() expires_delta to_encode.update({exp: expire}) encoded_jwt jwt.encode( to_encode, SECRET_KEY, algorithmALGORITHM, ) return encoded_jwt async def get_current_user(token: str Depends(oauth2_scheme)): credentials_exception HTTPException( status_codestatus.HTTP_401_UNAUTHORIZED, detailToken 无效或已过期, headers{WWW-Authenticate: Bearer}, ) try: payload jwt.decode( token, SECRET_KEY, algorithms[ALGORITHM], ) username payload.get(sub) if username is None: raise credentials_exception except JWTError: raise credentials_exception user fake_users_db.get(username) if user is None: raise credentials_exception return UserInfo(usernameuser[username], disableduser[disabled]) app.post(/login, response_modelTokenResponse) def login(form_data: OAuth2PasswordRequestForm Depends()): user authenticate_user( form_data.username, form_data.password, ) if not user: raise HTTPException( status_codestatus.HTTP_401_UNAUTHORIZED, detail用户名或密码错误, headers{WWW-Authenticate: Bearer}, ) access_token create_access_token( data{sub: user.username}, expires_deltatimedelta(minutesACCESS_TOKEN_EXPIRE_MINUTES), ) return { access_token: access_token, token_type: bearer, } app.get(/me, response_modelUserInfo) def read_current_user(current_user: UserInfo Depends(get_current_user)): return current_user app.get(/protected) def protected_api(current_user: UserInfo Depends(get_current_user)): return { message: 这是一个需要登录后才能访问的接口, user: current_user.username, }五、启动项目在main.py所在目录执行python -m uvicorn main:app --reload启动成功后浏览器访问http://127.0.0.1:8000/docs可以看到 FastAPI 自动生成的 Swagger 接口文档。六、测试账号本文示例内置了一个测试用户用户名admin 密码123456代码中使用hashed_password: pwd_context.hash(123456)运行时会自动生成密码哈希因此可以避免手动复制哈希字符串导致密码校验失败的问题。七、使用 Swagger 测试访问http://127.0.0.1:8000/docs点击右上角Authorize按钮。输入username: admin password: 123456认证成功后再访问GET /me GET /protected即可看到接口正常返回当前用户信息。八、使用命令行测试1. 登录获取 Token如果你使用的是 Windows PowerShell推荐使用curl.execurl.exe -X POST http://127.0.0.1:8000/login ^ -H Content-Type: application/x-www-form-urlencoded ^ -d usernameadminpassword123456如果你使用的是 macOS 或 Linuxcurl -X POST http://127.0.0.1:8000/login \ -H Content-Type: application/x-www-form-urlencoded \ -d usernameadminpassword123456返回结果示例{ access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx, token_type: bearer }2. 访问受保护接口将上一步返回的access_token放到请求头中。Windows PowerShellcurl.exe -X GET http://127.0.0.1:8000/protected ^ -H Authorization: Bearer 你的access_tokenmacOS 或 Linuxcurl -X GET http://127.0.0.1:8000/protected \ -H Authorization: Bearer 你的access_token成功返回示例{ message: 这是一个需要登录后才能访问的接口, user: admin }如果 Token 错误、缺失或过期则会返回 401。九、核心代码解析1. OAuth2PasswordBeareroauth2_scheme OAuth2PasswordBearer(tokenUrl/login)这行代码用于声明当前项目使用 Bearer Token 认证方式。当接口依赖oauth2_scheme时FastAPI 会自动从请求头中读取Authorization: Bearer token值2. 表单登录def login(form_data: OAuth2PasswordRequestForm Depends()):这里使用OAuth2PasswordRequestForm接收登录参数因此登录请求的格式是表单格式而不是 JSON 格式。请求参数为usernameadminpassword123456这种写法可以很好地配合 FastAPI 自带的 Swagger 授权功能。3. 密码校验def verify_password(plain_password: str, hashed_password: str) - bool: return pwd_context.verify(plain_password, hashed_password)项目中不要保存明文密码应保存加密后的密码哈希。本文为了方便演示直接在内存字典中模拟用户数据。4. 生成 JWTdef create_access_token(data: dict, expires_delta: timedelta): to_encode data.copy() expire datetime.utcnow() expires_delta to_encode.update({exp: expire}) encoded_jwt jwt.encode( to_encode, SECRET_KEY, algorithmALGORITHM, ) return encoded_jwt这里将用户身份信息和过期时间写入 JWT。其中sub通常用于保存用户唯一标识例如用户名或用户 ID。5. 校验 JWTpayload jwt.decode( token, SECRET_KEY, algorithms[ALGORITHM], )服务端使用相同的SECRET_KEY解析 Token。如果 Token 被篡改、签名不正确或已经过期解析时会抛出异常然后接口返回 401。6. 保护接口app.get(/protected) def protected_api(current_user: UserInfo Depends(get_current_user)):Depends(get_current_user)表示访问该接口前必须先完成 Token 校验。如果校验失败请求会直接返回 401不会继续执行接口主体。十、常见问题1. 为什么登录接口不是 JSON因为本文使用的是OAuth2PasswordRequestForm它接收的是表单格式数据方便和 FastAPI Swagger 的Authorize功能配合。如果想用 JSON 登录也可以自定义 Pydantic 模型但 Swagger 右上角的授权体验就没有这种方式直接。2. 为什么需要安装 python-multipart因为表单登录需要解析application/x-www-form-urlencoded或multipart/form-data类型的数据。如果没有安装python-multipart启动或请求时可能会出现表单解析相关错误。3. SECRET_KEY 可以随便写吗演示环境可以随便写但生产环境不建议硬编码在代码里。生产环境建议放到环境变量中例如JWT_SECRET_KEY一段足够复杂的随机字符串然后在代码中读取环境变量。4. Token 过期时间怎么设置本文设置为 30 分钟ACCESS_TOKEN_EXPIRE_MINUTES 30实际项目中需要根据业务场景决定。例如后台管理系统可以设置较短时间移动端应用可以结合 Refresh Token 延长登录状态高安全场景应设置更短有效期十一、实际项目优化方向本文示例为了便于理解使用内存字典模拟用户数据。真实项目中通常还需要做以下优化用户数据存储到数据库例如 MySQL、PostgreSQL、MongoDB。SECRET_KEY放到环境变量或配置中心。增加 Refresh Token 机制。增加用户注册接口。增加角色和权限控制。对 Token 加入黑名单机制用于支持主动退出登录。生产环境必须使用 HTTPS避免 Token 泄露。对登录接口增加限流防止暴力破解。统一封装认证异常和返回格式。按业务模块拆分目录结构避免所有代码写在一个文件中。十二、总结本文使用 FastAPI 实现了一个可直接运行的 JWT 登录认证示例完整覆盖了安装依赖、启动服务、登录获取 Token、携带 Token 访问受保护接口等流程。JWT 的优势是简单、无状态、适合前后端分离项目。掌握本文示例后可以继续扩展用户注册、权限控制、Refresh Token、后台管理系统登录等功能。对于 FastAPI 项目来说JWT 认证是非常常见的基础能力。建议在真实项目中结合数据库、环境变量、权限系统和统一异常处理进行进一步封装。

相关新闻

2027北京AI数字健康与智慧医疗展官方:30亿成交额背后

2027北京AI数字健康与智慧医疗展官方:30亿成交额背后

商业成交实效是衡量专业行业展会核心价值最直观的标尺,回顾上一届2026北京AI数字健康与智慧医疗赛逸展运营数据,展会全周期展前预约对接、现场签约洽谈、后期跟进落地的意向合作成交额整体突破30亿元,涵盖医疗设备批量采购、AI诊疗系统院内部…

2026/10/14 15:17:02 阅读更多 →
自带密钥AI可见性成本审计工具:从输入校验到离线报告的完整实现

自带密钥AI可见性成本审计工具:从输入校验到离线报告的完整实现

项目编号:20260813-003。本文代码、测试、文档、示例数据和效果图均为独立编写,不包含热点产品或开源项目源码、品牌素材与官方截图。 问题与目标 按查询、模型、供应商、缓存、失败重试和报告归属核算自带API密钥的可见性监测成本,不接触真…

2026/10/11 2:13:46 阅读更多 →
稳妥可信的中医药新模式 赋能现代健康管理发展

稳妥可信的中医药新模式 赋能现代健康管理发展

一、慢病时代来临,健康管理迎来转型需求当下,居民生活作息、饮食结构的持续变化,让慢性疾病成为影响国民身心健康的主要诱因,国内慢病患病群体规模持续扩大,国民健康需求也随之发生转变。以往以疾病治疗为核心的医疗模…

2026/10/10 6:56:16 阅读更多 →

最新新闻

2026年最新--区块链运营岗面试题库(100题)

2026年最新--区块链运营岗面试题库(100题)

一、行业趋势与运营思维(1-10题) 1. 2026年加密行业营销的核心趋势有哪些?请结合“用户质量优先”的转变,说明运营策略应如何调整。 2026年加密营销的7大核心趋势涵盖绩效营销、内容创作、渠道多元化、活动体验、激励机制以及AI驱动的运营。最关键的转变是:Fintech和Web…

2026/10/14 15:17:11 阅读更多 →
C# GPS定位到地图显示:NMEA解析、坐标转换与GMap.NET实战

C# GPS定位到地图显示:NMEA解析、坐标转换与GMap.NET实战

简介:面向C#开发者和GIS初学者的GPS定位与地图综合示例源码。项目基于.NET框架,展示如何使用GeoCoordinateWatcher获取NMEA GPS数据,并通过Bing Maps控件实现地图加载、缩放、平移及城市名地理编码定位,涵盖地图事件处理、UI布局、…

2026/10/14 15:17:11 阅读更多 →
HTML表单与表格实战:学生注册表单与课程表制作全解析

HTML表单与表格实战:学生注册表单与课程表制作全解析

做了几年前端开发,接手过不少新人带教和作业评审。说句实在话,不管后来技术栈换成React还是Vue,凡是能把HTML里的表单和表格玩明白的,上手业务系统的效率往往都不会太差。这两块看起来基础,里面的门道却一点也不少——…

2026/10/14 15:17:11 阅读更多 →
工业AI检测项目为何死于“全产线覆盖”?

工业AI检测项目为何死于“全产线覆盖”?

1. 那句“全产线覆盖”,到底杀死了什么我做了七八年机器视觉和上位机开发,前前后后参与过二十多个工业AI项目,从服装检测、3C外观检、到食品包装异物识别都碰过。如果让我总结这些项目失败的最大共性,不是算法不行,不是…

2026/10/14 15:17:11 阅读更多 →
微信小程序商城定制怎么落地?选型要点全拆解

微信小程序商城定制怎么落地?选型要点全拆解

其实, 微信小程序商城定制这事儿, 说起来就是搭建一套能够实现商品售卖、会员管理以及营销推广的线上商业闭环, 不要被“定制”这两个字给吓到了, 要知道现在的SaaS平台已经把所有的基础功能都变成了现成的模块状态, 这些模块大概占据了整体功能总量的百分之八十的比例, 因此, …

2026/10/14 15:17:11 阅读更多 →
fast-check 4.7.0 深度解析:stringMatching 支持 Unicode 属性转义与可逆的 json 生成器

fast-check 4.7.0 深度解析:stringMatching 支持 Unicode 属性转义与可逆的 json 生成器

开发工具测试 【免费下载链接】fast-check Property based testing framework for JavaScript (like QuickCheck) written in TypeScript 项目地址: https://gitcode.com/gh_mirrors/fa/fast-check 点击查看 免费下载 fast-check 4.7.0 是一个围绕"让生成器更…

2026/10/14 15:16:08 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →