具代表性的面試主題

前端面試:如何安全灰度 WebAuthn 條件式建立?

前端困難
Offer.cc 編輯團隊發佈 更新

題幹

你要在既有密碼登入頁中灰度 WebAuthn 條件式建立,讓瀏覽器在使用者輸入帳號時提示建立 passkey。如何設計前端能力偵測、伺服器驗證與失敗回退?

題幹與適用情境

產品已有使用者名稱、密碼與條件式取得的 passkey 登入。現在希望在使用者完成一次高信任登入後,利用 WebAuthn Level 3 的 conditional create,在不打斷流程的情況下建議建立 passkey。請說明瀏覽器能力偵測、建立條件、伺服器校驗、隱私邊界與回滾策略。

題目聚焦 Web 平台與認證互動。不要把「瀏覽器支援 API」當成「裝置一定有可用驗證器」;建立仍需使用者同意與伺服器驗證。

面試官考察點

  • 能否區分 conditional create、conditional get 與明確按鈕建立。
  • 能否在能力、策略、使用者狀態與跨裝置同步之間建立清楚門檻。
  • 能否避免重複建立、誤綁帳號、洩露憑據存在性,或讓失敗阻塞密碼登入。
  • 能否設計可觀測的灰度與撤回,而不是一次性開啟新 API。

強回答會把條件式建立當作增強路徑:能力偵測失敗或使用者拒絕時主流程不變,伺服器仍驗證 challenge、origin、RP ID 與使用者歸屬。

回答前需要釐清的問題

  1. 目標是所有已登入使用者,還是只針對已驗證信箱、完成 MFA 或高風險操作後的使用者?
  2. 是否允許建立多裝置同步的 passkey?帳戶復原與撤銷策略會因此改變。
  3. 目前前端是否已經有未完成的 credentials.create() 請求?並行請求會產生難以解釋的提示。
  4. 瀏覽器不支援 conditional create 時,是否顯示明確的「建立 passkey」按鈕,還是完全隱藏?

30 秒回答框架

「我先用 WebAuthn 能力偵測確認瀏覽器支援 conditional create,再結合帳戶狀態、最近認證強度與伺服器 feature flag 決定是否嘗試。前端只在使用者明確允許的時機發起一次建立,並用 AbortController 取消重複請求;任何不支援、取消或逾時都回到原登入流程。伺服器為一次性 challenge 綁定使用者、origin、RP ID 與過期時間,驗證成功後才保存 credential。灰度觀察建立成功率、取消率、重複憑據、登入回退率與復原工單;異常時關閉 flag,已建立的憑據仍可單獨撤銷。」

分步驟深入解答

1. 區分兩種條件式互動

conditional get 讓使用者在輸入帳號時選擇已有 passkey;conditional create 則是在表單情境中建議建立新憑據。兩者都依賴瀏覽器與驗證器能力,不能只檢查 PublicKeyCredential 物件就斷言可用。

能力偵測結果只決定是否嘗試,不決定是否授權。伺服器仍應把註冊 challenge 綁定到目前已認證使用者,並記錄建立來源與策略版本。

2. 設計建立門檻

建議同時滿足:瀏覽器報告支援 conditional create;使用者已完成足夠強度的認證;帳戶不在復原、合併或高風險變更;伺服器 feature flag 對該租戶與流量視窗開放。新裝置可先顯示說明,再由使用者繼續,而不是頁面載入時靜默建立。

3. 防止重複與競態

每個頁面工作階段最多一個建立請求。開始新請求前取消舊請求,元件卸載時也取消。伺服器 challenge 使用一次即失效,credential ID 設唯一約束;重複提交回傳冪等結果,不建立第二筆記錄。

text
capability -> policy gate -> one challenge -> user consent
      |            |               |
   fallback   feature flag     server verify -> persist

4. 完整驗證註冊結果

伺服器驗證 challenge、origin、RP ID、簽章、使用者 handle、attestation 策略與 credential ID。不要只相信前端回傳的「建立成功」。若不需要裝置證明,可採用較簡單的 attestation 策略,但必須說明隱私與風控取捨。

5. 處理同步與復原

多裝置同步的 passkey 讓使用者換裝置後仍可能看到憑據,但同步不等於帳戶復原。提供查看裝置、撤銷單一 credential、失去所有裝置後的復原流程;不要把是否存在 passkey 暴露給未認證請求。

6. 灰度與可觀測性

按瀏覽器、平台、租戶與風險等級分批開啟。記錄能力偵測通過率、建立提示出現率、使用者同意率、驗證失敗原因、取消/逾時、重複 credential、密碼回退率與支援工單。指標要區分「瀏覽器不支援」與「使用者拒絕」,否則無法決定改文案還是關閉功能。

7. 回滾與相容

用遠端 flag 關閉新建立嘗試,保留既有 passkey 的登入能力。撤回時不刪除憑據,避免把發布回滾誤做成帳戶破壞。伺服器保留舊 challenge 版本的有限驗證視窗並設定期限;規範或瀏覽器行為改變後重新進行相容測試。

高品質示範回答

我會把 conditional create 當作可撤回的增強路徑。前端先檢查瀏覽器能力,再由帳戶狀態、最近認證強度與 feature flag 決定是否嘗試;每個頁面工作階段只允許一個請求,重複請求用 AbortController 取消。伺服器為目前使用者產生一次性 challenge,校驗 challenge、origin、RP ID、簽章與 credential ID 後才保存。使用者取消、不支援或逾時都回到密碼登入,不把失敗當成登入失敗。灰度按平台與風險分批,觀察能力通過率、同意率、驗證失敗、重複憑據、回退率與復原工單。關閉 flag 只停止新建立,保留既有 passkey 與撤銷能力。

常見錯誤

  • 錯誤表現 → 只檢查 PublicKeyCredential 是否存在 → 物件存在不代表 conditional create 與驗證器都可用;修正方法:使用能力偵測並保留回退路徑。
  • 錯誤表現 → 頁面載入就靜默呼叫建立 → 使用者未同意且容易產生重複提示;修正方法:在明確的高信任時機觸發,讓使用者控制繼續。
  • 錯誤表現 → 只在前端判斷成功 → challenge、origin 或帳戶歸屬可能未驗證;修正方法:伺服器完成完整註冊驗證。
  • 錯誤表現 → 回滾時刪除已建立憑據 → 發布回退變成帳戶破壞;修正方法:關閉新建立 flag,憑據撤銷獨立處理。

追問及應對

使用者拒絕建立後是否每天再提示?

不要無限提示。記錄本地冷卻期與伺服器策略版本,只有帳戶風險、裝置或產品條件顯著變化時再詢問;拒絕本身不應影響密碼登入。

同一帳戶出現兩個相同 credential ID 怎麼辦?

把 credential ID 設為唯一鍵,註冊介面做冪等處理並記錄來源。若資料庫已有重複資料,先凍結新增寫入,再按使用者與 credential ID 合併或人工審核,不能靜默覆蓋。

瀏覽器支援能力但建立成功率突然下降,先查什麼?

先按瀏覽器版本、平台、驗證器類型與錯誤碼切片,區分使用者取消、逾時、策略拒絕與伺服器驗證失敗。暫停受影響分組的 flag,保留密碼與既有 passkey 登入,修復後用小流量重新驗證。

公開來源

同類題目