安全性入門
公開 API 幾乎都要回答:「這個人是誰、他能不能做這件事」。FastAPI 不幫你選資料庫或發 JWT 的函式庫,但提供與 OAuth2 對齊的依賴,讓認證邏輯可以掛在任何端點上。
先建立正確的心智模型
- 認證(authentication):確認身分(token / 密碼是否有效)。
- 授權(authorization):確認這個身分可不可以做這件事。
- 雜湊密碼:只用經過審查的演算法(例如
pwdlib/ bcrypt),密碼明文既不存也不寫進 log。 - JWT:適合無狀態 API,但簽名金鑰要放環境變數,過期時間要設,不要把敏感資料塞進 payload。
自己拼「Base64 一下當 token」或「用 MD5 存密碼」都會在正式環境出事。跟框架無關,是密碼學常識。
OAuth2 密碼流程的最小形狀
官方教學用 OAuth2 Password flow:客戶端把帳號密碼 POST 到 /token,伺服器回 access_token,之後請求在 Authorization: Bearer <token> 帶著它。
from typing import Annotated
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
user = users_from_token(token)
if user is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="無效的認證資訊",
headers={"WWW-Authenticate": "Bearer"},
)
return user
@app.get("/me")
def read_me(current_user: Annotated[dict, Depends(get_current_user)]):
return current_user
OAuth2PasswordBearer 做兩件事:從 header 取出 token,以及讓 /docs 出現 Authorize 按鈕。真正「token 怎麼簽、怎麼驗」寫在 users_from_token 裡,通常搭配 pwdlib 與 PyJWT。
需要登入的端點一律 Depends(get_current_user);需要管理員再包一層檢查 role 的依賴。不要在每個函式裡複製貼上解 token 的程式。
CORS 常被當成安全問題
瀏覽器會擋跨來源的前端請求。API 若要給瀏覽器裡的 SPA 呼叫,需設定 CORS 中介軟體,並明確列出允許的來源,不要在正式環境用 allow_origins=["*"] 搭配 allow_credentials=True。
CORS 不是認證,它只影響瀏覽器。手機 App 或伺服器對伺服器呼叫不受同源政策限制,仍要做 token 檢查。
進一步學習
- 官方:安全性簡介
- 官方:OAuth2 與密碼(第一堂)
- 官方:OAuth2 與 JWT
- 官方:CORS
- OWASP Authentication Cheat Sheet
- 完整專案起點:Full Stack FastAPI Template(已含 JWT、密碼雜湊)
- 下一頁:測試