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

WebOTP API 現在可以從 iframe 中接收動態密碼。

簡訊動態密碼 (動態密碼) 通常用於驗證電話號碼,例如做為驗證或線上驗證付款的第二個步驟。不過,在瀏覽器和簡訊應用程式間切換、進行複製貼上或手動輸入 OTP 時,很容易出錯,並增加使用者體驗。

WebOTP API 可讓網站透過程式輔助方式從簡訊中取得動態密碼,而且只要輕觸一下即可自動依格式輸入密碼,使用者不必切換應用程式。簡訊會經過特殊格式且繫結至來源,因此也能減輕網路釣魚網站竊取動態密碼的機會。

WebOTP 還無法支援的其中一種用途,就是指定 iframe 內的來源。這通常用於確認付款,特別是搭配 3D Secure 時。WebOTP API 現在提供支援跨來源 iframe 的通用格式,從 Chrome 91 版開始,現在能夠傳送繫結至巢狀來源的動態密碼。

WebOTP API 的運作方式

WebOTP API 本身就夠簡單:

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

簡訊必須使用來源繫結的一次性代碼格式化

Your OTP is: 123456.

@web-otp.glitch.me #12345

請注意,在最後一行中,包含的起點會繫結在前面加上 @,後面接著 OTP 前面加上 #

簡訊收到時,畫面上會彈出資訊列,並提示使用者驗證電話號碼。使用者按一下 Verify 按鈕後,瀏覽器會自動將動態密碼轉送至網站,並解析 navigator.credentials.get()。網站即可擷取動態密碼並完成驗證程序。

如要瞭解 WebOTP 的基本概念,請參閱「使用 WebOTP API 驗證網路上的電話號碼」。

跨來源 iframe 用途

在付款情境中,以跨來源 iframe 的形式輸入動態密碼是常見的做法。部分信用卡發卡機構需要額外的驗證步驟,才能確認付款人的真實性。這項做法稱為 3D Secure,此表單通常會顯示在相同頁面的 iframe 中,就像是付款流程的一部分。

例如:

  • 使用者造訪 shop.example 並用信用卡購買了一雙鞋,
  • 輸入信用卡號後,整合的付款服務供應商會在 iframe 中顯示 bank.example 的表單,要求使用者驗證電話號碼以快速結帳。
  • bank.example 會向使用者傳送含有動態密碼的簡訊,以便使用者輸入這組動態密碼並驗證身分。

如何從跨來源 iframe 使用 WebOTP API

如要從跨來源 iframe 中使用 WebOTP API,您需要執行以下兩項操作:

  • 在簡訊中,同時為頂端頁框來源和 iframe 來源加上註解。
  • 設定權限政策,允許跨來源 iframe 直接接收來自使用者的動態密碼。
iframe 中的 WebOTP API 實際運作情形。

您可以在 https://web-otp-iframe-demo.stackblitz.io 自行嘗試示範。

為簡訊簡訊的繫結來源加上註解

如果從 iframe 內呼叫 WebOTP API,簡訊文字訊息必須包含頂端頁框來源 (前面加上 @,後面接有 # 的 OTP,後面緊接在 @ 後方的 iframe 來源)。

@shop.example #123456 @bank.exmple

設定權限政策

如要在跨來源 iframe 中使用 WebOTP,嵌入程式必須透過虛擬憑證權限政策授予這個 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 網站上)