使用 WebOTP API 在跨來源 iframe 中填入動態密碼表單

WebOTP API 現在可在 iframe 中接收 OTP。

簡訊動態密碼 (OTP) 通常用於驗證電話號碼,例如做為驗證程序的第二步驟,或驗證網站上的付款。不過,在瀏覽器和簡訊應用程式之間切換,以便複製貼上或手動輸入 OTP,很容易出錯,也會影響使用者體驗。

WebOTP API 可讓網站以程式輔助方式從簡訊中取得一次性密碼,並自動將其輸入表單,讓使用者只需輕觸一下即可完成,無須切換應用程式。簡訊採用特殊格式,且會繫結至來源,因此可降低釣魚網站竊取一次性密碼的機會。

WebOTP 尚未支援的用途之一,是指定 iframe 內的來源。這通常用於付款確認,尤其是搭配 3D Secure 時。有了支援跨來源 iframe 的通用格式,WebOTP API 現可從 Chrome 91 開始提供綁定至巢狀來源的 OTP。

WebOTP API 的運作方式

WebOTP API 本身相當簡單:

…
  const otp = await navigator.credentials.get({
    otp: { transport:['sms'] }
  });
…

SMS 訊息必須採用來源限定的一次性驗證碼格式

Your OTP is: 123456.

@web-otp.glitch.me #12345

請注意,最後一行包含要繫結的來源,前面有 @,後面有 OTP,前面有 #

收到簡訊後,系統會彈出資訊列,提示使用者驗證電話號碼。使用者按下 Verify 按鈕後,瀏覽器會自動將 OTP 轉寄至網站,並解析 navigator.credentials.get()。網站就能擷取 OTP 並完成驗證程序。

如要瞭解 WebOTP 的基本用法,請參閱「使用 WebOTP API 在網站上驗證電話號碼」一文。

跨來源 iframe 用途

在跨來源 iframe 中的表單中輸入動態密碼,是付款情境中常見的做法。部分信用卡發卡機構會要求額外的驗證步驟,以便檢查付款者的真實性。這稱為 3D Secure,表單通常會在同一頁面的 iframe 中顯示,就像是付款流程的一部分。

例如:

  • 使用者造訪 shop.example,並使用信用卡購買一雙鞋子。
  • 輸入信用卡號碼後,整合式付款服務供應商會在 iframe 中顯示來自 bank.example 的表單,要求使用者驗證電話號碼,以便快速結帳。
  • bank.example 會傳送含有 OTP 的簡訊給使用者,方便他們輸入驗證碼來驗證身分。

如何從跨來源 iframe 使用 WebOTP API

如要在跨來源 iframe 中使用 WebOTP API,您必須執行兩項操作:

  • 在簡訊文字訊息中註解頂層框架來源和 iframe 來源。
  • 設定權限政策,允許跨來源 iframe 直接從使用者接收 OTP。
iframe 內的 WebOTP API 運作情形。

您可以前往 https://web-otp-iframe-demo.stackblitz.io 親自試用這個範例。

在簡訊中標註繫結來源

從 iframe 中呼叫 WebOTP API 時,簡訊必須包含前面有 @ 的頂層框架來源,接著是前面有 # 的 OTP,接著是前面有 @ 的 iframe 來源。

@shop.example #123456 @bank.exmple

設定權限政策

如要在跨來源 iframe 中使用 WebOTP,嵌入者必須透過 otp-credentials 權限政策授予此 API 存取權,以免發生非預期行為。一般來說,有兩種方法可以達成這個目標:

  • 透過 HTTP 標頭:
Permissions-Policy: otp-credentials=(self "https://bank.example")
  • 透過 iframe allow 屬性:
<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>

請參閱其他如何指定權限政策的範例

注意事項

巢狀層級

目前 Chrome 僅支援跨來源 iframe 的 WebOTP API 呼叫,且該 iframe 在其祖系鏈結中不超過一個不重複的來源。在下列情況下:

  • a.com -> b.com
  • a.com -> b.com -> b.com
  • a.com -> a.com -> b.com
  • a.com -> b.com -> c.com

系統支援在 b.com 使用 WebOTP,但不支援在 c.com 使用。

請注意,由於缺乏需求和使用者體驗複雜性,因此系統也不支援下列情況。

  • a.com -> b.com -> a.com (呼叫 WebOTP API)

互通性

雖然 Chromium 以外的瀏覽器引擎不會實作 WebOTP API,但 Safari 會透過 input[autocomplete="one-time-code"] 支援共用相同的 簡訊格式。在 Safari 中,只要收到含有與來源相符的一次性代碼格式的簡訊,鍵盤就會建議在輸入欄位中輸入 OTP。

自 2021 年 4 月起,Safari 支援使用 % 的專屬簡訊格式的 iframe。不過,由於規格討論結論是改用 @,因此我們希望支援的簡訊格式實作方式能統一。

意見回饋

您的意見對 WebOTP API 的改良十分重要,歡迎試用並與我們分享您的想法。

資源

相片來源:rupixen.com 提供,取自 Unsplash