ยืนยันหมายเลขโทรศัพท์บนเว็บด้วย WebOTP API

ช่วยเหลือผู้ใช้ที่มี OTP ที่ได้รับผ่าน SMS

WebOTP API คืออะไร

ปัจจุบันนี้ คนส่วนใหญ่บนโลกมีอุปกรณ์เคลื่อนที่ และนักพัฒนาซอฟต์แวร์มักจะใช้หมายเลขโทรศัพท์เป็นตัวระบุผู้ใช้บริการของตน

การยืนยันหมายเลขโทรศัพท์ทำได้หลายวิธี แต่การใช้รหัสผ่านแบบครั้งเดียว (OTP) ที่สร้างขึ้นแบบสุ่มซึ่งส่งทาง SMS เป็นวิธีหนึ่งที่ใช้กันมากที่สุด การส่งโค้ดนี้กลับไปยังเซิร์ฟเวอร์ของนักพัฒนาซอฟต์แวร์แสดงถึงการควบคุมหมายเลขโทรศัพท์

แนวคิดนี้มีการนำไปใช้แล้วในหลายๆ สถานการณ์เพื่อให้บรรลุวัตถุประสงค์ต่อไปนี้

  • หมายเลขโทรศัพท์เป็นตัวระบุให้ผู้ใช้ เมื่อลงชื่อสมัครใช้บริการใหม่ บางเว็บไซต์จะขอหมายเลขโทรศัพท์แทนที่อยู่อีเมลและใช้หมายเลขดังกล่าวเป็นตัวระบุบัญชี
  • การยืนยันแบบ 2 ขั้นตอน เมื่อลงชื่อเข้าใช้ เว็บไซต์จะขอรหัสแบบใช้ครั้งเดียวที่ส่งทาง SMS นอกเหนือจากรหัสผ่านหรือปัจจัยความรู้อื่นเพื่อเพิ่มความปลอดภัย
  • การยืนยันการชำระเงิน เมื่อผู้ใช้ชำระเงิน การขอรหัสแบบครั้งเดียวที่ส่งทาง SMS จะช่วยยืนยันเจตนาของผู้ใช้ได้

กระบวนการในปัจจุบันสร้างอุปสรรคให้กับผู้ใช้ การค้นหา OTP ภายในข้อความ SMS แล้วคัดลอกและวางลงในแบบฟอร์มอาจเป็นเรื่องยุ่งยาก ทำให้อัตรา Conversion ในเส้นทางที่สำคัญของผู้ใช้ลดลง การค่อยๆ เปลี่ยนนี่เป็นคำขอเว็บที่มีมาอย่างยาวนานจากนักพัฒนาซอฟต์แวร์รายใหญ่ที่สุดระดับโลกมากมาย Android มี API ที่ทำหน้าที่นี้อย่างเคร่งครัด เช่นเดียวกับ iOS และ Safari

WebOTP API ช่วยให้แอปของคุณรับข้อความที่มีรูปแบบพิเศษซึ่งผูกกับโดเมนของแอปได้ ด้วยวิธีการนี้ คุณจะสามารถรับ OTP ทางโปรแกรมจากข้อความ SMS และยืนยันหมายเลขโทรศัพท์ให้ผู้ใช้ได้ง่ายขึ้น

ดูของจริง

สมมติว่าผู้ใช้ต้องการยืนยันหมายเลขโทรศัพท์กับเว็บไซต์ เว็บไซต์จะส่งข้อความไปยังผู้ใช้ผ่าน SMS และผู้ใช้ป้อน OTP จากข้อความเพื่อยืนยันความเป็นเจ้าของหมายเลขโทรศัพท์

WebOTP API ช่วยให้ผู้ใช้ทำขั้นตอนต่างๆ ได้ง่ายด้วยการแตะเพียงครั้งเดียว ดังที่แสดงในวิดีโอ เมื่อได้รับข้อความดังกล่าว Bottom Sheet จะปรากฏขึ้นและแจ้งให้ผู้ใช้ยืนยันหมายเลขโทรศัพท์ หลังจากคลิกปุ่มยืนยันใน Bottom Sheet เบราว์เซอร์จะวาง OTP ลงในแบบฟอร์มและส่งแบบฟอร์มโดยที่ผู้ใช้ไม่จำเป็นต้องกดต่อไป

กระบวนการทั้งหมดมีแผนภาพอยู่ในรูปภาพด้านล่าง

แผนภาพ WebOTP API

ลองดูเดโมด้วยตัวคุณเอง ระบบจะไม่ขอหมายเลขโทรศัพท์หรือส่ง SMS ไปยังอุปกรณ์ แต่คุณจะส่งหมายเลขจากอุปกรณ์อื่นโดยคัดลอกข้อความที่แสดงในการสาธิตได้ ซึ่งใช้งานได้เพราะผู้ส่ง ไม่ว่าใครจะเป็นผู้ส่งเมื่อใช้ WebOTP API

  1. ไปที่ https://web-otp.glitch.me ใน Chrome 84 ขึ้นไปบนอุปกรณ์ Android
  2. ส่งข้อความ SMS ต่อไปนี้จากโทรศัพท์เครื่องอื่นไปยังโทรศัพท์ของคุณ
Your OTP is: 123456.

@web-otp.glitch.me #12345

คุณได้รับ SMS และเห็นข้อความแจ้งให้ป้อนรหัสในพื้นที่อินพุตไหม ซึ่งเป็นวิธีการทำงานของ WebOTP API สำหรับผู้ใช้

การใช้ WebOTP API ประกอบด้วย 3 ส่วนดังนี้

  • แท็ก <input> ที่มีคำอธิบายประกอบอย่างเหมาะสม
  • JavaScript ในเว็บแอปของคุณ
  • ส่งข้อความที่จัดรูปแบบผ่านทาง SMS

ฉันจะพูดถึงแท็ก <input> ก่อน

ใส่คำอธิบายประกอบในแท็ก <input>

WebOTP ทำงานได้โดยไม่ต้องใช้คำอธิบายประกอบ HTML แต่สำหรับความเข้ากันได้ข้ามเบราว์เซอร์ เราขอแนะนำให้คุณเพิ่ม autocomplete="one-time-code" ลงในแท็ก <input> ที่คุณต้องการให้ผู้ใช้ป้อน OTP

การดำเนินการนี้จะช่วยให้ Safari 14 ขึ้นไปแนะนําให้ผู้ใช้ป้อนข้อมูลอัตโนมัติในช่อง <input> ด้วย OTP เมื่อได้รับ SMS ในรูปแบบที่อธิบายไว้ในจัดรูปแบบข้อความ SMS แม้ว่าจะไม่รองรับ WebOTP ก็ตาม

HTML

<form>
  <input autocomplete="one-time-code" required/>
  <input type="submit">
</form>

ใช้ WebOTP API

เนื่องจาก WebOTP ใช้งานง่าย เพียงคัดลอกและวางโค้ดต่อไปนี้ก็จะทำงานได้แล้ว เราจะคอยแนะนำสิ่งที่เกิดขึ้น

JavaScript

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      input.value = otp.code;
      if (form) form.submit();
    }).catch(err => {
      console.log(err);
    });
  });
}

การตรวจหาฟีเจอร์

การตรวจหาฟีเจอร์นั้นเหมือนกับ API อื่นๆ อีกมาก การฟังเหตุการณ์ DOMContentLoaded จะรอให้แผนผัง DOM พร้อมค้นหา

JavaScript

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    …
    const form = input.closest('form');
    …
  });
}

ประมวลผล OTP

WebOTP API เองนั้นใช้งานง่ายพอ ใช้ navigator.credentials.get() เพื่อรับ OTP WebOTP เพิ่มตัวเลือก otp ใหม่ไปยังวิธีการดังกล่าว แต่มีพร็อพเพอร์ตี้เพียงรายการเดียวเท่านั้น: transport ซึ่งค่าต้องเป็นอาร์เรย์ที่มีสตริง 'sms'

JavaScript

    …
    navigator.credentials.get({
      otp: { transport:['sms'] }
      …
    }).then(otp => {
    …

ซึ่งจะทริกเกอร์โฟลว์สิทธิ์ของเบราว์เซอร์เมื่อมีข้อความ SMS เข้ามา หากได้รับสิทธิ์แล้ว สัญญาที่ส่งคืนจะแก้ไขด้วยออบเจ็กต์ OTPCredential

เนื้อหาของออบเจ็กต์ OTPCredential ที่ได้รับ

{
  code: "123456" // Obtained OTP
  type: "otp"  // `type` is always "otp"
}

ต่อไป ให้ส่งค่า OTP ไปยังช่อง <input> การส่งแบบฟอร์มโดยตรงจะกำจัดขั้นตอนที่กำหนดให้ผู้ใช้ต้องแตะปุ่ม

JavaScript

    …
    navigator.credentials.get({
      otp: { transport:['sms'] }
      …
    }).then(otp => {
      input.value = otp.code;
      if (form) form.submit();
    }).catch(err => {
      console.error(err);
    });
    …

ล้มเลิกข้อความ

ในกรณีที่ผู้ใช้ป้อน OTP ด้วยตนเองและส่งแบบฟอร์ม คุณจะยกเลิกการเรียกใช้ get() ได้โดยใช้อินสแตนซ์ AbortController ในออบเจ็กต์ options

JavaScript

    …
    const ac = new AbortController();
    …
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    …
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
    …

จัดรูปแบบข้อความ SMS

ตัว API ควรดูเรียบง่าย แต่มีบางอย่างที่คุณควรทราบก่อนที่จะใช้งาน ข้อความจะต้องส่งหลังจากที่เรียก navigator.credentials.get() แล้ว และจะต้องได้รับข้อความในอุปกรณ์ที่มีการโทร get() สุดท้าย ข้อความต้องเป็นไปตามการจัดรูปแบบต่อไปนี้

  • ข้อความจะขึ้นต้นด้วย (ไม่บังคับ) ข้อความที่มนุษย์อ่านได้ซึ่งมีสตริงตัวอักษรและตัวเลขคละกัน 4-10 อักขระ โดยมีตัวเลขอย่างน้อย 1 ตัวออกจากบรรทัดสุดท้ายสำหรับ URL และ OTP
  • ส่วนโดเมนของ URL ของเว็บไซต์ที่เรียกใช้ API จะต้องอยู่ต่อจาก @
  • URL ต้องมีเครื่องหมายสี่เหลี่ยม (#) ตามด้วย OTP

เช่น

Your OTP is: 123456.

@www.example.com #123456

ตัวอย่างที่ไม่ดีมีดังนี้

ตัวอย่างข้อความ SMS ที่มีรูปแบบไม่ถูกต้อง สาเหตุที่ไม่ได้ผล
Here is your code for @example.com #123456 @ ควรเป็นอักขระแรกของบรรทัดสุดท้าย
Your code for @example.com is #123456 @ ควรเป็นอักขระแรกของบรรทัดสุดท้าย
Your verification code is 123456

@example.com\t#123456
ต้องมีการเว้นวรรค 1 ช่องระหว่าง @host ถึง #code
Your verification code is 123456

@example.com  #123456
ต้องมีการเว้นวรรค 1 ช่องระหว่าง @host ถึง #code
Your verification code is 123456

@ftp://example.com #123456
ไม่สามารถรวมรูปแบบ URL ได้
Your verification code is 123456

@https://example.com #123456
ไม่สามารถรวมรูปแบบ URL ได้
Your verification code is 123456

@example.com:8080 #123456
ไม่สามารถรวมพอร์ตได้
Your verification code is 123456

@example.com/foobar #123456
ไม่สามารถรวมเส้นทางได้
Your verification code is 123456

@example .com #123456
ไม่มีช่องว่างในโดเมน
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
ไม่มีอักขระต้องห้ามในโดเมน
@example.com #123456

Mambo Jumbo
คาดว่า @host และ #code จะเป็นบรรทัดสุดท้าย
@example.com #123456

App hash #oudf08lkjsdf834
คาดว่า @host และ #code จะเป็นบรรทัดสุดท้าย
Your verification code is 123456

@example.com 123456
ไม่มี #
Your verification code is 123456

example.com #123456
ไม่มี @
Hi mom, did you receive my last text ไม่มี @ และ #

เดโม

ลองใช้ข้อความที่หลากหลายในการสาธิต https://web-otp.glitch.me

นอกจากนี้ คุณยังสามารถแยกและสร้างเวอร์ชันได้ที่ https://glitch.com/edit/#!/web-otp

ใช้ WebOTP จาก iframe แบบข้ามต้นทาง

โดยทั่วไปแล้ว การป้อน SMS OTP ไปยัง iframe แบบข้ามต้นทางจะใช้ในการยืนยันการชำระเงิน โดยเฉพาะอย่างยิ่งเมื่อใช้ 3D Secure WebOTP API ใช้รูปแบบทั่วไปเพื่อรองรับ iframe แบบข้ามต้นทาง โดยจะนำส่ง OTP ที่ผูกกับต้นทางที่ซ้อนกันอยู่ เช่น

  • ผู้ใช้ไปที่ shop.example เพื่อซื้อรองเท้าด้วยบัตรเครดิต
  • หลังจากป้อนหมายเลขบัตรเครดิตแล้ว ผู้ให้บริการชำระเงินที่ผสานรวมจะแสดงแบบฟอร์มจาก bank.example ใน iframe เพื่อขอให้ผู้ใช้ยืนยันหมายเลขโทรศัพท์เพื่อชำระเงินอย่างรวดเร็ว
  • bank.example จะส่ง SMS ที่มี OTP ให้กับผู้ใช้เพื่อให้ผู้ใช้ป้อน OTP เพื่อยืนยันตัวตนได้

หากต้องการใช้ WebOTP API จากใน iframe แบบข้ามต้นทาง คุณต้องดำเนินการ 2 อย่างต่อไปนี้

  • ใส่คำอธิบายประกอบทั้งต้นทางของเฟรมด้านบนและต้นทางของ iframe ในข้อความ SMS
  • กำหนดค่านโยบายสิทธิ์เพื่ออนุญาตให้ iframe แบบข้ามต้นทางรับ OTP จากผู้ใช้โดยตรง
WebOTP API ภายใน iframe ในการดำเนินการ

คุณลองใช้การสาธิตได้ที่ https://web-otp-iframe-demo.stackblitz.io

ใส่คำอธิบายประกอบต้นทางที่ผูกมัดกับข้อความ SMS

เมื่อมีการเรียก WebOTP API จากภายใน iframe ข้อความ SMS ต้องมีต้นทางของเฟรมด้านบนซึ่งขึ้นต้นด้วย @ ตามด้วย OTP ที่ขึ้นต้นด้วย # และต้นทาง iframe ที่นำหน้าด้วย @ ในบรรทัดสุดท้าย

Your verification code is 123456

@shop.example #123456 @bank.exmple

กำหนดค่านโยบายสิทธิ์

หากต้องการใช้ WebOTP ใน iframe แบบข้ามต้นทาง ผู้ฝังต้องให้สิทธิ์เข้าถึง API นี้ผ่านนโยบายสิทธิ์ของข้อมูลเข้าสู่ระบบ otp-credentials เพื่อหลีกเลี่ยงลักษณะการทำงานที่ไม่ตั้งใจ โดยทั่วไปแล้ว มี 2 วิธีในการบรรลุเป้าหมายนี้ ได้แก่

ผ่านส่วนหัว HTTP

Permissions-Policy: otp-credentials=(self "https://bank.example")

ผ่านแอตทริบิวต์ allow ของ iframe ดังนี้

<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>

ดูตัวอย่างเพิ่มเติมเกี่ยวกับวิธีระบุนโยบายสิทธิ์

ใช้ WebOTP บนเดสก์ท็อป

ใน Chrome WebOTP รองรับการฟัง SMS ที่ได้รับในอุปกรณ์อื่นๆ เพื่อช่วยสนับสนุนผู้ใช้ในการยืนยันหมายเลขโทรศัพท์บนเดสก์ท็อป

WebOTP API บนเดสก์ท็อป

ความสามารถนี้กำหนดให้ผู้ใช้ต้องลงชื่อเข้าใช้บัญชี Google เดียวกันทั้งในเดสก์ท็อป Chrome และ Android Chrome

นักพัฒนาแอปทั้งหมดต้องทำคือการใช้ WebOTP API ในเว็บไซต์บนเดสก์ท็อปด้วยวิธีเดียวกับที่ทำในเว็บไซต์บนอุปกรณ์เคลื่อนที่ แต่ไม่จำเป็นต้องใช้กลเม็ดพิเศษใดๆ

ดูรายละเอียดเพิ่มเติมได้ที่ยืนยันหมายเลขโทรศัพท์บนเดสก์ท็อปโดยใช้ WebOTP API

คำถามที่พบบ่อย

กล่องโต้ตอบไม่ปรากฏขึ้นแม้ว่าฉันกำลังส่งข้อความที่จัดรูปแบบอย่างถูกต้อง เกิดอะไรขึ้น

มีข้อควรระวังอยู่ 2 ข้อเมื่อทดสอบ API ดังนี้

  • หากหมายเลขโทรศัพท์ของผู้ส่งอยู่ในข้อมูลรายชื่อติดต่อของผู้รับ ระบบจะไม่เรียกใช้ API นี้เนื่องจากการออกแบบ SMS User Consent API ที่สำคัญ
  • หากคุณใช้โปรไฟล์งานในอุปกรณ์ Android และ WebOTP ใช้งานไม่ได้ ให้ลองติดตั้งและใช้ Chrome ในโปรไฟล์ส่วนตัวแทน (เช่น โปรไฟล์เดียวกับที่คุณรับข้อความ SMS)

โปรดกลับมาตรวจสอบรูปแบบเพื่อดูว่า SMS อยู่ในรูปแบบที่ถูกต้องหรือไม่

API นี้เข้ากันได้กับเบราว์เซอร์ต่างๆ หรือไม่

Chromium และ WebKit เห็นด้วยกับรูปแบบข้อความ SMS และ Apple ได้ประกาศการรองรับการใช้งาน Safari เริ่มตั้งแต่ iOS 14 และ macOS Big Sur แม้ว่า Safari จะไม่รองรับ WebOTP JavaScript API แต่การใส่คำอธิบายประกอบในองค์ประกอบ input ด้วย autocomplete=["one-time-code"] แป้นพิมพ์เริ่มต้นจะแนะนำให้คุณป้อน OTP โดยอัตโนมัติหากข้อความ SMS เป็นไปตามรูปแบบดังกล่าว

การใช้ SMS เป็นวิธีตรวจสอบสิทธิ์ปลอดภัยไหม

SMS OTP มีประโยชน์ในการยืนยันหมายเลขโทรศัพท์เมื่อให้หมายเลขครั้งแรก แต่การยืนยันหมายเลขโทรศัพท์ผ่าน SMS จะต้องใช้ในการตรวจสอบสิทธิ์อีกครั้งอย่างระมัดระวัง เนื่องจากผู้ให้บริการอาจลักลอบใช้หมายเลขโทรศัพท์และนำกลับมาใช้ใหม่ได้ WebOTP เป็นกลไกการตรวจสอบสิทธิ์ซ้ำและการกู้คืนที่สะดวก แต่บริการควรรวมกับปัจจัยอื่นๆ ด้วย เช่น การพิสูจน์ความรู้ หรือใช้ Web Authentication API เพื่อการตรวจสอบสิทธิ์อย่างเข้มงวด

ฉันจะรายงานข้อบกพร่องในการใช้งาน Chrome ได้ที่ใด

คุณพบข้อบกพร่องในการใช้งาน Chrome หรือไม่

  • รายงานข้อบกพร่องที่ https://new.crbug.com ระบุรายละเอียดให้มากที่สุดเท่าที่จะทำได้ วิธีการง่ายๆ ในการทำซ้ำ และตั้งค่าคอมโพเนนต์เป็น Blink>WebOTP

ฉันจะช่วยฟีเจอร์นี้ได้อย่างไร

คุณวางแผนที่จะใช้ WebOTP API หรือไม่ การสนับสนุนแบบสาธารณะของคุณจะช่วยให้เราจัดลำดับความสำคัญของฟีเจอร์ และแสดงให้ผู้ให้บริการเบราว์เซอร์รายอื่นๆ เห็นว่าการสนับสนุนฟีเจอร์เหล่านั้นสำคัญเพียงใด ส่งทวีตไปที่ @ChromiumDev โดยใช้แฮชแท็ก #WebOTP และแจ้งให้เราทราบว่าคุณใช้แฮชแท็กนี้ที่ไหนและอย่างไร

แหล่งข้อมูล