在构建现代 Web 应用程序时,身份验证和授权 是两个不可避免的核心问题。FastAPI 提供了一种简洁而强大的方式来处理身份验证,特别是通过 OAuth2 这种标准协议。在这篇文章中,我们将详细介绍 FastAPI 中的 OAuth2PasswordBearer
授权机制,并结合代码实例来理解其工作原理。
OAuth2PasswordBearer
是 OAuth2 标准中的一种授权模式。它假设客户端通过发送一个 Bearer token (通常是通过密码登录获取的)来请求资源。这个 token 可以用于访问受保护的 API。
在 FastAPI 中,OAuth2PasswordBearer
是一种依赖注入,它会自动从请求中提取 Bearer token。
首先,确保你已经安装了 FastAPI
和 uvicorn
:
pip install fastapi uvicorn
OAuth2PasswordBearer
接下来,我们将定义一个 OAuth2PasswordBearer 实例,它会从请求的 Authorization 头中提取 Bearer token:
from fastapi import FastAPI, Depends
from fastapi.security import OAuth2PasswordBearer
from fastapi.exceptions import HTTPException
from starlette.status import HTTP_401_UNAUTHORIZED
app = FastAPI()
# 定义 OAuth2PasswordBearer 实例
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 一个简单的路径,要求有 Bearer token
@app.get("/users/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
return {"token": token}
解释:
tokenUrl="token"
:OAuth2PasswordBearer
需要指定一个 URL 用于获取 token。客户端会向该 URL 提交用户名和密码来请求 token。Depends(oauth2_scheme)
:FastAPI 的依赖注入系统,会自动从请求中提取并验证 token。要完成 OAuth2 的授权流程,我们需要定义一个 token endpoint,客户端可以通过它来请求 token。
from pydantic import BaseModel
from fastapi import Form
class Token(BaseModel):
access_token: str
token_type: str
@app.post("/token", response_model=Token)
async def login(username: str = Form(), password: str = Form()):
if username == "test" and password == "secret":
return {"access_token": "fake-token", "token_type": "bearer"}
raise HTTPException(
status_code=HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Bearer"},
)
解释:
Form()
:用于从表单中提取用户名和密码。response_model=Token
:返回的 JSON 结构与 Token
模型匹配。一旦我们定义了获取 token 的逻辑,我们就可以用这个 token 访问受保护的 API 路由。
@app.get("/protected-route")
async def protected_route(token: str = Depends(oauth2_scheme)):
if token != "fake-token":
raise HTTPException(
status_code=HTTP_401_UNAUTHORIZED,
detail="Invalid token",
headers={"WWW-Authenticate": "Bearer"},
)
return {"message": "Welcome to the protected route!"}
解释:
Depends(oauth2_scheme)
:从请求中提取 token。现在,你可以通过以下命令运行应用:
uvicorn main:app --reload
在终端中访问 http://127.0.0.1:8000/docs
,你会看到 FastAPI 的交互式文档。在这里,你可以尝试调用 /token
路由获取 token,然后将 token 应用于 /protected-route
,以验证授权机制的工作。
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
from fastapi import Form
from starlette.status import HTTP_401_UNAUTHORIZED
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
class Token(BaseModel):
access_token: str
token_type: str
@app.post("/token", response_model=Token)
async def login(username: str = Form(), password: str = Form()):
if username == "test" and password == "secret":
return {"access_token": "fake-token", "token_type": "bearer"}
raise HTTPException(
status_code=HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Bearer"},
)
@app.get("/users/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
return {"token": token}
@app.get("/protected-route")
async def protected_route(token: str = Depends(oauth2_scheme)):
if token != "fake-token":
raise HTTPException(
status_code=HTTP_401_UNAUTHORIZED,
detail="Invalid token",
headers={"WWW-Authenticate": "Bearer"},
)
return {"message": "Welcome to the protected route!"}
在本文中,我们学习了如何使用 FastAPI 中的 OAuth2PasswordBearer
来实现身份验证和授权。通过使用 FastAPI 提供的依赖注入系统,我们可以轻松地将授权逻辑集成到 API 路由中,并确保只有合法的请求才会被授权访问受保护的资源。OAuth2 是处理身份验证的强大工具,而 FastAPI 则为我们提供了简洁的实现方式。