iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0
生成式 AI

30 天與 AI 同事打造系統的求生實錄系列 第 14

【Day 14】Swagger UI的鎖頭迷思:從 OAuth2 到 HTTPBearer 的認證探索

  • 分享至 

  • xImage
  •  

今天是鐵人賽第十四天,繼續處理昨天的 Swagger UI 上的 Available authorizations 沒有內容的問題,因為這個問題昨天AI同事卡了很久,我今天打算人工介入處理。
由於主要是人工去處理,我就不細寫與AI同事互動的過程了。

我先把 logout 的程式給小幫手 ChatGPT,請它幫忙分析錯誤原因。它指出回傳的部分是一個物件而不是 token,因此建議我使用 token.credentials 來取出 token 內容。雖然後來發現這並不是造成問題的真正原因,但用 token.credentials 取得變數值,相對來說比較穩定,也不容易因版本不同而出錯就沿用了。

在翻了很多資料之後,我開始思考一個現象:為什麼有時使用 OAuth2PasswordBearer 時,Swagger UI上測試 API時,鎖頭會出現 Available authorizations 的內容,可以直接測試認證;但如果改用 HTTPBearer,鎖頭內的 Available authorizations 就會是空的(Empty)。

我進一步查看了 FastAPI 的原始碼,包括 OAuth2PasswordBearer()HTTPBearer()get_openapi(),並請 AI 同事幫忙分析後,整理出一版使用方法說明。這些方法在 Swagger UI 都能正常顯示鎖頭,讓你測試 API 認證,但有一些重要發現:

  • 單一使用這些方法通常沒問題。
  • 不同方法一起使用時,有些可以共存,有些會互相衝突,導致 Available authorizations 變成空的。
  • 衝突的情況依認證方式而異(例如帳密認證、直接 token 認證等),這種問題很容易被忽略,因為程式不會報錯。

雖然這次只是為了方便性才去找問題,對功能影響不大,但如果未來遇到會影響功能的情況,這種無回饋的衝突會非常棘手。這次是 AI 同事「埋的」BUG,但即便不是 AI 同事,一般人也很容易誤用而出現類似問題。

在修 BUG 的過程中,我把 FastAPI 的原始碼函數貼給 AI,請它幫忙整理輸入輸出來研究,在程式註解寫得很好的情況下,AI 的幫助還是非常大的;但如果只是單純從應用層去互動請AI思考處理,現階段這種類型的 BUG 仍然很難解決。

下面是這次 AI 同事使用的驗證方式整理。原本想測試各方法各自組合的結果,但過程太麻煩且耗時,而且版本一更新可能結果就會改變,因此這裡只列出方法,供其他人參考是否也有遇到同樣的問題。

FastAPI API 函數認證方式整理

使用方式 用途
API 函數內使用 HTTPBearer() 從 HTTP Authorization Header 取得 Bearer Token,供依賴函數進行認證檢查
API 函數內使用 OAuth2PasswordBearer() 從 HTTP Authorization Header 取得 OAuth2 Bearer Token,供依賴函數進行認證檢查
app.include_router(..., dependencies=[Depends(get_current_user)]) 將依賴套用到 router 下所有 API,進行執行時的認證檢查
自訂 openapi_schema["components"]["securitySchemes"](在自訂義 openapi 變數中) 定義 API 可用的認證方式(HTTP Bearer、OAuth2 等)
設置 openapi_schema["security"] = [{"BearerAuth": []}](在自訂義 openapi 變數中) 將指定 security scheme 套用到全局 API
手動設置 openapi_schema["paths"]["/test"]["get"]["security"] = [{"BearerAuth": []}](在自訂義 openapi 變數中) 針對單個 API 路由指定 security

上一篇
【Day 13】從帳密到 Bearer:和 AI 同事的一場認證迷宮探險
下一篇
【Day 15】差點回到過去:從驚魂到掌控的專案管理功能規劃
系列文
30 天與 AI 同事打造系統的求生實錄30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言