API安全大揭秘:认证与授权的双面舞会
title: API安全大揭秘:认证与授权的双面舞会
date: 2025/05/28 12:14:35
updated: 2025/05/28 12:14:35
author: cmdragon
excerpt:
API安全的核心需求包括认证与授权机制。认证验证用户身份,如用户名密码登录;授权验证用户是否有权限执行特定操作,如管理员删除数据。典型安全威胁包括未授权访问、凭证泄露和权限提升。FastAPI通过OpenAPI规范支持OAuth2、HTTP Basic等安全方案,依赖注入系统实现灵活验证。OAuth2协议通过授权请求、授权许可、访问令牌等步骤确保安全访问。FastAPI实现OAuth2密码流程示例包括环境准备、核心代码实现和运行测试,确保用户身份验证和权限控制。
categories:
- 后端开发
- FastAPI
tags:
- API安全
- 认证与授权
- OAuth2协议
- FastAPI
- 安全威胁
- 依赖注入
- 访问令牌


扫描二维码
关注或者微信搜一搜:编程智域 前端至全栈交流与成长
探索数千个预构建的 AI 应用,开启你的下一个伟大创意:https://tools.cmdragon.cn/
第一章:理解API安全的基本需求
为什么需要认证与授权机制
认证(Authentication)与授权(Authorization)的区别
- 认证:验证用户身份的过程(例如:用户名密码登录)。
类比:进入公司大楼时出示工牌(证明你是员工)
- 授权:验证用户是否有权限执行特定操作(例如:管理员删除数据)。
类比:不同工牌对应不同的门禁权限(普通员工不能进入机房)
典型安全威胁场景
- 未授权访问:攻击者直接调用
/admin/delete-data
接口删除数据 - 凭证泄露:用户密码在传输过程中被窃取
- 权限提升:普通用户越权访问管理员接口
FastAPI的安全设计原则
- 内置支持OpenAPI规范的安全方案(OAuth2、HTTP Basic等)
- 通过依赖注入系统实现灵活的安全验证逻辑
- 自动生成交互式API文档中的安全测试界面
OAuth2协议在Web服务中的应用场景
OAuth2核心概念图解
+--------+ +---------------+
| |--(A) 授权请求 ->---------------| 资源所有者 |
| | | (用户) |
| |<-(B) 授权许可 ----------------| |
| | +---------------+
| |
| | +---------------+
| |--(C) 授权许可 ->---------------| 授权服务器 |
| 客户端 | | (签发令牌) |
| |<-(D) 访问令牌 ----------------| |
| | +---------------+
| |
| | +---------------+
| |--(E) 访问令牌 ->---------------| 资源服务器 |
| | | (存储数据) |
| |<-(F) 受保护资源 --------------| |
+--------+ +---------------+
FastAPI实现OAuth2密码流程示例
环境准备
# 安装依赖库(指定版本保证兼容性)
pip install fastapi==0.68.0 uvicorn==0.15.0
pip install python-jose[cryptography]==3.3.0
pip install passlib[bcrypt]==1.7.4
核心代码实现
from fastapi import Depends, FastAPI, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from passlib.context import CryptContext
from pydantic import BaseModel
from datetime import datetime, timedelta
# 安全配置常量
SECRET_KEY = "your-secret-key-here"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
# 密码加密上下文
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# OAuth2方案声明
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 用户数据模型
class User(BaseModel):
username: str
disabled: bool = False
class UserInDB(User):
hashed_password: str
# 令牌生成函数
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
# 认证依赖项
async def get_current_user(token: str = Depends(oauth2_scheme)):
credential_exception = HTTPException(
status_code=401,
detail="无法验证凭证",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise credential_exception
except JWTError:
raise credential_exception
# 实际项目应查询数据库
user = UserInDB(
username=username,
hashed_password="fakehash",
disabled=False
)
if user.disabled:
raise HTTPException(status_code=400, detail="用户已被禁用")
return user
app = FastAPI()
@app.post("/token")
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
# 验证用户名密码(示例硬编码)
if form_data.username != "testuser" or form_data.password != "testpass":
raise HTTPException(
status_code=401,
detail="用户名或密码错误",
headers={"WWW-Authenticate": "Bearer"},
)
access_token = create_access_token(
data={"sub": form_data.username}
)
return {"access_token": access_token, "token_type": "bearer"}
@app.get("/protected/")
async def read_protected_route(current_user: User = Depends(get_current_user)):
return {"message": "已授权访问", "user": current_user.username}
运行与测试
uvicorn main:app --reload
打开浏览器访问 http://localhost:8000/docs
,在Swagger界面中:
- 点击
/token
端点,输入测试凭证(username: testuser, password: testpass) - 复制返回的access_token
- 点击
/protected/
端点,在Authorization弹窗中输入Bearer <your-token>
课后Quiz
Q1:认证与授权的根本区别是什么?
A) 认证确认身份,授权验证权限
B) 授权在前,认证在后
C) 两者是同义词
点击查看答案
正确答案:A
解析:认证是验证用户身份的过程(如登录),授权是验证该身份是否有权限执行特定操作(如访问管理员接口)。
Q2:OAuth2的授权码流程包含哪些主要步骤?
A) 客户端直接获取访问令牌
B) 用户授权 → 获取授权码 → 交换访问令牌
C) 用户名密码直接传递给资源服务器
点击查看答案
正确答案:B
解析:完整的授权码流程需要通过授权服务器中转授权码,避免客户端直接接触用户凭证。
常见报错解决方案
报错:422 Unprocessable Entity
{
"detail": [
{
"loc": [
"body",
"password"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
原因分析:
- 请求体缺少必填字段(如password字段)
- 字段数据类型不匹配(例如数字传入了字符串)
解决方法:
- 检查Swagger文档中的请求体模型
- 使用Postman验证请求体格式:
{
"username": "testuser",
"password": "testpass"
}
- 在Pydantic模型中使用
...
表示必填字段:
class LoginRequest(BaseModel):
username: str
password: str # 必填字段
预防建议:
- 启用Pydantic的严格模式:
from pydantic import StrictStr
class LoginRequest(BaseModel):
username: StrictStr
password: StrictStr
- 在路由中使用
response_model_exclude_unset=True
过滤未设置字段
余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
,阅读完整的文章:API安全大揭秘:认证与授权的双面舞会 | cmdragon's Blog
往期文章归档:
- 异步日志监控:FastAPI与MongoDB的高效整合之道 | cmdragon's Blog
- FastAPI与MongoDB分片集群:异步数据路由与聚合优化 | cmdragon's Blog
- FastAPI与MongoDB Change Stream的实时数据交响曲 | cmdragon's Blog
- 地理空间索引:解锁日志分析中的位置智慧 | cmdragon's Blog
- 异步之舞:FastAPI与MongoDB的极致性能优化之旅 | cmdragon's Blog
- 异步日志分析:MongoDB与FastAPI的高效存储揭秘 | cmdragon's Blog
- MongoDB索引优化的艺术:从基础原理到性能调优实战 | cmdragon's Blog
- 解锁FastAPI与MongoDB聚合管道的性能奥秘 | cmdragon's Blog
- 异步之舞:Motor驱动与MongoDB的CRUD交响曲 | cmdragon's Blog
- 异步之舞:FastAPI与MongoDB的深度协奏 | cmdragon's Blog
- 数据库迁移的艺术:FastAPI生产环境中的灰度发布与回滚策略 | cmdragon's Blog
- 数据库迁移的艺术:团队协作中的冲突预防与解决之道 | cmdragon's Blog
- 驾驭FastAPI多数据库:从读写分离到跨库事务的艺术 | cmdragon's Blog
- 数据库事务隔离与Alembic数据恢复的实战艺术 | cmdragon's Blog
- FastAPI与Alembic:数据库迁移的隐秘艺术 | cmdragon's Blog
- 飞行中的引擎更换:生产环境数据库迁移的艺术与科学 | cmdragon's Blog
- Alembic迁移脚本冲突的智能检测与优雅合并之道 | cmdragon's Blog
- 多数据库迁移的艺术:Alembic在复杂环境中的精妙应用 | cmdragon's Blog
- 数据库事务回滚:FastAPI中的存档与读档大法 | cmdragon's Blog
- Alembic迁移脚本:让数据库变身时间旅行者 | cmdragon's Blog
- 数据库连接池:从银行柜台到代码世界的奇妙旅程 | cmdragon's Blog
- 点赞背后的技术大冒险:分布式事务与SAGA模式 | cmdragon's Blog
- N+1查询:数据库性能的隐形杀手与终极拯救指南 | cmdragon's Blog
- FastAPI与Tortoise-ORM开发的神奇之旅 | cmdragon's Blog
- DDD分层设计与异步职责划分:让你的代码不再“异步”混乱 | cmdragon's Blog
- 异步数据库事务锁:电商库存扣减的防超卖秘籍 | cmdragon's Blog
- FastAPI中的复杂查询与原子更新指南 | cmdragon's Blog
- 深入解析Tortoise-ORM关系型字段与异步查询 | cmdragon's Blog
- FastAPI与Tortoise-ORM模型配置及aerich迁移工具 | cmdragon's Blog
- 异步IO与Tortoise-ORM的数据库 | cmdragon's Blog
- FastAPI数据库连接池配置与监控 | cmdragon's Blog
- 分布式事务在点赞功能中的实现 | cmdragon's Blog
- Tortoise-ORM级联查询与预加载性能优化 | cmdragon's Blog
- 使用Tortoise-ORM和FastAPI构建评论系统 | cmdragon's Blog
- XML Sitemap
API安全大揭秘:认证与授权的双面舞会的更多相关文章
- API代理网关和OAuth2.0授权认证框架
API代理网关和OAuth2.0授权认证框架 https://www.cnblogs.com/bluedoctor/p/8967951.html 1,授权认证与微服务架构 1.1,由不同团队合作引发的 ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(二)
上文已经介绍了Identity Service的实现过程.今天我们继续,实现一个简单的Weather API和一个基于Ocelot的API网关. 回顾 <Angular SPA基于Ocelot ...
- 【高德地图API】汇润做爱地图技术大揭秘
原文:[高德地图API]汇润做爱地图技术大揭秘 昨日收到了高德地图微信公众号的消息推送,说有[一大波免费情趣用品正在袭来],点进去看了一眼,说一个电商公司(估计是卖情趣用品的)用高德云图制作了一张可以 ...
- 【高德地图API】从零开始学高德JS API(七)——定位方式大揭秘
原文:[高德地图API]从零开始学高德JS API(七)——定位方式大揭秘 摘要:关于定位,分为GPS定位和网络定位2种.GPS定位,精度较高,可达到10米,但室内不可用,且超级费电.网络定位,分为w ...
- 【从零开始搭建自己的.NET Core Api框架】(七)授权认证进阶篇
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
- Web Api 2 认证与授权 2
HTTP Message Handler 在 Web Api 2 认证与授权 中讲解了几种实现机制,本篇就详细讲解 Message Handler 的实现方式 关于 Message Handler 在 ...
- 关于 Web Api 2 认证与授权
认证与授权 认证与授权,Authentication and Authorize,这个是两个不同的事.认证是对访问身份进行确认,如验证用户名和密码,而授权是在认证之后,判断是否具有权限进行某操作,如 ...
- .Netcore 2.0 Ocelot Api网关教程(5)- 认证和授权
本文介绍Ocelot中的认证和授权(通过IdentityServer4),本文只使用最简单的IdentityServer,不会对IdentityServer4进行过多讲解. 1.Identity Se ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(四)
在上一讲中,我们已经完成了一个完整的案例,在这个案例中,我们可以通过Angular单页面应用(SPA)进行登录,然后通过后端的Ocelot API网关整合IdentityServer4完成身份认证.在 ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(一)
好吧,这个题目我也想了很久,不知道如何用最简单的几个字来概括这篇文章,原本打算取名<Angular单页面应用基于Ocelot API网关与IdentityServer4+ASP.NET Iden ...
随机推荐
- SQLserver查询用逗号隔开的字段中是否包含另一个字段的值
CHARINDEX(','+用逗号隔开的字段+',',','+是否包含的字段+',')>0 大于0则存在
- 【VMware by Broadcom】VMware 产品套件(2025)
VMware 被 Broadcom 收购后(现为 VMware by Broadcom),重新调整了其产品部门并最终优化为了四个,分别是:VMware Cloud Foundation(VCF)部门. ...
- FastAPI 核心安全功能与模板渲染的完整示:登录、CSRF、JWT、会话、认证和缓存功能
以下是一个整合 FastAPI 核心安全功能与模板渲染的完整示例,基于多个技术文档的最佳实践,包含登录.CSRF.JWT.会话.认证和缓存功能: from datetime import dateti ...
- PMP学习记录
本人在2020年12月已经顺利拿到PMP证书. 第一次听说PMP证书是2016年,一个同事说考试通过拿到了PMP证书,当时对PMP不是很了解.也未作深入了解,当时认为俺是做技术的,这个证书没啥用.O( ...
- idea的deployment没有war包
一.解决方案
- mybatis——分页插件PageHelper的使用
项目开发中涉及列表查询时,经常会需要对查询结果进行分页处理:常用的一个插件--PageHelper,是国内非常优秀的一款开源的mybatis分页插件,它支持基本主流与常用的数据库,一致支持mysql. ...
- should contain指令的用法,校验结果
上图案例 商品添加后,匹配"商品名称","现价","库存" 首先获取"商品名称","现价",&quo ...
- SearXNG+MCP实现搜索引擎,想怎么搜就怎么搜
一.概述 MCP应用市场,有很多搜索引擎的应用.但是你们会发现,普遍都需要api-key.你必须花钱购买api-key才能实现搜索功能. 问题来了,我就想用免费搜索的,就向百度一样,可不可以? 答案是 ...
- 理解.NET Core中的配置Configuration
什么是配置 .NET中的配置,本质上就是key-value键值对,并且key和value都是字符串类型. 在.NET中提供了多种配置提供程序来对不同的配置进行读取.写入.重载等操作,这里我们以为.NE ...
- Junit单元测试的Gradle设置
官方文档 https://docs.gradle.org/current/userguide/java_testing.html test{ useJUnit() //指定使用junit执行测试. / ...