題幹與適用情境
產品已有使用者名稱、密碼與條件式取得的 passkey 登入。現在希望在使用者完成一次高信任登入後,利用 WebAuthn Level 3 的 conditional create,在不打斷流程的情況下建議建立 passkey。請說明瀏覽器能力偵測、建立條件、伺服器校驗、隱私邊界與回滾策略。
題目聚焦 Web 平台與認證互動。不要把「瀏覽器支援 API」當成「裝置一定有可用驗證器」;建立仍需使用者同意與伺服器驗證。
面試官考察點
- 能否區分 conditional create、conditional get 與明確按鈕建立。
- 能否在能力、策略、使用者狀態與跨裝置同步之間建立清楚門檻。
- 能否避免重複建立、誤綁帳號、洩露憑據存在性,或讓失敗阻塞密碼登入。
- 能否設計可觀測的灰度與撤回,而不是一次性開啟新 API。
強回答會把條件式建立當作增強路徑:能力偵測失敗或使用者拒絕時主流程不變,伺服器仍驗證 challenge、origin、RP ID 與使用者歸屬。
回答前需要釐清的問題
- 目標是所有已登入使用者,還是只針對已驗證信箱、完成 MFA 或高風險操作後的使用者?
- 是否允許建立多裝置同步的 passkey?帳戶復原與撤銷策略會因此改變。
- 目前前端是否已經有未完成的
credentials.create()請求?並行請求會產生難以解釋的提示。 - 瀏覽器不支援 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 設唯一約束;重複提交回傳冪等結果,不建立第二筆記錄。
capability -> policy gate -> one challenge -> user consent
| | |
fallback feature flag server verify -> persist4. 完整驗證註冊結果
伺服器驗證 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 登入,修復後用小流量重新驗證。