在构建现代化的 Web 应用程序时,用户身份验证和授权是不可或缺的组成部分。FastAPI 提供了多种方法来实现鉴权,以确保只有授权用户可以访问特定的资源或执行特定的操作。本文将介绍 FastAPI 中的鉴权方法,包括基本概念、实践案例和一些提示和技巧。
FastAPI 中鉴权的基本概念
在开始讨论具体的鉴权方法之前,让我们先了解一些基本概念:
1.认证(Authentication):认证是确定用户身份的过程。通常,用户需要提供凭证(例如用户名和密码)来进行认证。
2.授权(Authorization):授权是确定用户是否有权限执行特定操作或访问特定资源的过程。一旦用户成功认证,授权规则将确定他们可以执行的操作。
3.Token:Token 是一种代表用户身份的令牌。通常,用户在成功登录后会获得一个 Token,然后在每个后续请求中将其包含在头部或请求参数中。
4.Middleware:中间件是在处理请求之前或之后执行的代码段,可用于添加额外的处理逻辑,包括鉴权。
FastAPI 中的鉴权方法
1. 基本 HTTP 认证
基本 HTTP 认证是最简单的鉴权方式之一,它要求用户提供用户名和密码。FastAPI 可以使用 Python 的base64
模块来解码 HTTP 头中的用户名和密码。
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI()
security = HTTPBasic()
# 鉴权路由
@app.get("/secure-data/")
async def secure_data(credentials: HTTPBasicCredentials = Depends(security)):
if credentials.username == "user" and credentials.password == "password":
return {"message": "鉴权成功"}
else:
raise HTTPException(status_code=401, detail="鉴权失败")
2. OAuth2.0
OAuth2.0 是一种更复杂的鉴权方法,允许用户通过第三方服务进行鉴权。FastAPI 提供了OAuth2PasswordBearer
、OAuth2PasswordRequestForm
等工具来简化 OAuth2.0 的实现。
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
app = FastAPI()
security = OAuth2PasswordBearer(tokenUrl="/token")
# 鉴权路由
@app.get("/secure-data/")
async def secure_data(token: str = Depends(security)):
# 验证token的逻辑
if verify_token(token):
return {"message": "鉴权成功"}
else:
raise HTTPException(status_code=401, detail="鉴权失败")
3. 自定义鉴权中间件
如果需要更高度定制的鉴权逻辑,可以编写自定义的鉴权中间件。这允许你完全控制鉴权过程,并在每个请求之前进行处理。
from fastapi import FastAPI, Depends, HTTPException
from my_auth_middleware import CustomAuthMiddleware
app = FastAPI()
# 使用自定义鉴权中间件
app.add_middleware(CustomAuthMiddleware)
# 鉴权路由
@app.get("/secure-data/")
async def secure_data():
return {"message": "鉴权成功"}
实践案例
为了演示鉴权方法,下面创建一个基于 FastAPI 的简单 API,其中包括两个路由:一个公开的路由和一个需要鉴权的路由。我们将使用基本 HTTP 认证作为鉴权方法,并为每个路由添加详细的注释。
首先,确保已经安装了 FastAPI 和 uvicorn:
pip install fastapi uvicorn
现在,我们来创建一个名为 main.py
的文件,包含以下内容:
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI()
# 创建一个基本HTTP认证的实例
security = HTTPBasic()
# 模拟存储的用户名和密码(实际应用中应该从数据库或其他安全存储中获取)
users_db = {
"user": {
"username": "user",
"password": "password"
}
}
# 鉴权路由
@app.get("/secure-data/")
async def secure_data(credentials: HTTPBasicCredentials = Depends(security)):
"""
需要鉴权的路由示例
:param credentials: FastAPI 提供的用于解析HTTP Basic Auth头部的对象
:return: 成功时返回鉴权成功的消息,否则返回鉴权失败的HTTP错误
"""
# 验证用户名和密码是否匹配
user = users_db.get(credentials.username)
if user is None or user["password"] != credentials.password:
raise HTTPException(status_code=401, detail="鉴权失败")
return {"message": "鉴权成功"}
# 公开路由
@app.get("/")
async def public_data():
"""
公开路由示例
:return: 一个公开的消息,无需鉴权
"""
return {"message": "这是一个公开的路由,无需鉴权"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="localhost", port=8000)
在上述代码中,我们创建了一个 FastAPI 应用,包含两个路由。public_data
路由是公开的,不需要鉴权。而 secure_data
路由使用基本 HTTP 认证来进行鉴权。
要运行这个示例,可以使用以下命令:
uvicorn main:app --reload
现在,你可以在浏览器或 API 客户端中访问 http://localhost:8000/secure-data/
来测试需要鉴权的路由,并提供正确的用户名和密码。同时,也可以访问 http://localhost:8000/
来测试公开的路由,无需鉴权。
提示、技巧和注意事项
- 始终使用 HTTPS 来保护用户凭据的传输。
- 存储密码时,应使用密码哈希来存储,而不是明文密码。
- 仔细管理和保护你的鉴权令牌,以防止安全漏洞。
- 了解和遵循 OAuth2.0 和其他鉴权协议的最佳实践,以确保应用程序的安全性。
使用 Apifox 调试 FastAPI 接口
如果你是 FastAPI 开发者,你经常需要与 API 打交道,确保你的应用程序能够正常工作。这时,一个强大的接口测试工具就会派上用场。
Apifox 是一个比 Postman 更强大的接口测试工具,Apifox = Postman + Swagger + Mock + JMeter,Apifox 支持调试 http(s)、WebSocket、Socket、gRPC、Dubbo 等协议的接口,并且集成了 IDEA 插件。在写完服务接口时,测试阶段可以通过 Apifox 来校验接口的正确性,图形化界面极大的方便了项目的上线效率。
如果想快速的调试一条接口,新建一个项目后,在项目中选择“调试模式”,填写请求地址后即可快速发送请求,并获得响应结果,上文的实践案例如图所示:
总结
FastAPI 提供了多种灵活的鉴权方法,使你能够选择最适合你的应用程序需求的方式。从基本 HTTP 认证到 OAuth2.0 和自定义鉴权中间件,FastAPI 为构建安全的 Web 应用程序提供了强大的工具和支持。
知识扩展:
- Spring Boot Actuator 是什么?Spring Boot Actuator 的使用方法及用途
- Spring Boot Thymeleaf 如何使用? Spring Boot Thymeleaf 的用法
参考链接:
- FastAPI 官方文档:https://fastapi.tiangolo.com/
- OAuth2.0 官方文档:https://oauth.net/2/
- Python base64 模块文档:https://docs.python.org/3/library/base64.html