今天是鐵人賽第十四天,繼續處理昨天的 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 認證,但有一些重要發現:
雖然這次只是為了方便性才去找問題,對功能影響不大,但如果未來遇到會影響功能的情況,這種無回饋的衝突會非常棘手。這次是 AI 同事「埋的」BUG,但即便不是 AI 同事,一般人也很容易誤用而出現類似問題。
在修 BUG 的過程中,我把 FastAPI 的原始碼函數貼給 AI,請它幫忙整理輸入輸出來研究,在程式註解寫得很好的情況下,AI 的幫助還是非常大的;但如果只是單純從應用層去互動請AI思考處理,現階段這種類型的 BUG 仍然很難解決。
下面是這次 AI 同事使用的驗證方式整理。原本想測試各方法各自組合的結果,但過程太麻煩且耗時,而且版本一更新可能結果就會改變,因此這裡只列出方法,供其他人參考是否也有遇到同樣的問題。
使用方式 | 用途 |
---|---|
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 |