Skip to content

建立 2026-09-14 更新 2026-09-14

安全性入門

公開 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 檢查。

進一步學習