โดยทั่วไปแล้ว เราจะขอให้ผู้ใช้ระบุรหัสผ่านที่สามารถใช้งานได้เพียงครั้งเดียว (OTP) เพื่อยืนยันตัวตน ด้วยการส่ง SMS กรณีการใช้งาน OTP ทาง SMS บางส่วนมีดังนี้
- การตรวจสอบสิทธิ์แบบ 2 ปัจจัย นอกจากชื่อผู้ใช้และรหัสผ่านแล้ว OTP ทาง SMS ยังใช้เป็นสัญญาณที่รัดกุมได้ว่าบัญชีเป็นของบุคคลที่ได้รับ OTP ทาง SMS
- การยืนยันหมายเลขโทรศัพท์ บางบริการใช้หมายเลขโทรศัพท์เป็นตัวระบุหลักของผู้ใช้ ในบริการดังกล่าว ผู้ใช้สามารถป้อนหมายเลขโทรศัพท์และ OTP ที่ได้รับทาง SMS เพื่อพิสูจน์ตัวตน บางครั้งก็ใช้ร่วมกับ PIN เพื่อสร้างการตรวจสอบสิทธิ์แบบ 2 ปัจจัย
- การกู้คืนบัญชี เมื่อผู้ใช้สูญเสียสิทธิ์เข้าถึงบัญชี จะต้องมีวิธีในการกู้คืนบัญชี การส่งอีเมลไปยังอีเมลที่ลงทะเบียนไว้หรือ การส่ง OTP ทาง SMS ไปยังหมายเลขโทรศัพท์เป็นวิธีการกู้คืนบัญชีที่ใช้กันโดยทั่วไป
- การยืนยันการชำระเงิน ในระบบการชำระเงิน ธนาคารหรือผู้ออกบัตรเครดิตบางราย ขอการตรวจสอบสิทธิ์เพิ่มเติมจากผู้ชำระเงินด้วยเหตุผลด้านความปลอดภัย โดยทั่วไปแล้วจะใช้ OTP ทาง SMS เพื่อวัตถุประสงค์ดังกล่าว
อ่านต่อเพื่อดูแนวทางปฏิบัติแนะนำในการสร้างแบบฟอร์ม OTP ทาง SMS สำหรับกรณีการใช้งานเหล่านี้
เช็กลิสต์
หากต้องการมอบประสบการณ์การใช้งานที่ดีที่สุดให้แก่ผู้ใช้ด้วย OTP ทาง SMS ให้ทำตามขั้นตอนต่อไปนี้
- ใช้องค์ประกอบ
<input>
กับรายการต่อไปนี้type="text"
inputmode="numeric"
autocomplete="one-time-code"
- ใช้
@BOUND_DOMAIN #OTP_CODE
เป็นบรรทัดสุดท้ายของข้อความ SMS ที่มีรหัส OTP - ใช้ WebOTP API
ใช้องค์ประกอบ <input>
การใช้แบบฟอร์มที่มีองค์ประกอบ <input>
เป็นแนวทางปฏิบัติแนะนำที่สำคัญที่สุดที่คุณ
ทำตามได้ เนื่องจากใช้ได้ในทุกเบราว์เซอร์ แม้ว่าคำแนะนำอื่นๆ จากโพสต์นี้จะใช้ไม่ได้ในบางเบราว์เซอร์ แต่ผู้ใช้จะยังคงป้อนและส่ง OTP ได้ด้วยตนเอง
<form action="/verify-otp" method="POST">
<input type="text"
inputmode="numeric"
autocomplete="one-time-code"
pattern="\d{6}"
required>
</form>
ต่อไปนี้เป็นแนวคิดบางส่วนที่จะช่วยให้ช่องป้อนข้อมูลได้รับประโยชน์สูงสุดจากฟังก์ชันการทำงานของเบราว์เซอร์
type="text"
เนื่องจากโดยปกติแล้ว OTP จะเป็นตัวเลข 5 หรือ 6 หลัก การใช้
type="number"
สำหรับช่องป้อนข้อมูลจึงอาจดูใช้งานง่ายเนื่องจากจะเปลี่ยนแป้นพิมพ์บนอุปกรณ์เคลื่อนที่
ให้เป็นตัวเลขเท่านั้น เราไม่แนะนำให้ทำเช่นนี้เนื่องจากเบราว์เซอร์คาดหวังว่าช่องป้อนข้อมูลจะเป็นตัวเลขที่นับได้ ไม่ใช่ลำดับของตัวเลขหลายตัว
ซึ่งอาจทำให้เกิดลักษณะการทำงานที่ไม่คาดคิด การใช้ type="number"
จะทำให้ปุ่มขึ้นและลง
ปรากฏข้างช่องป้อนข้อมูล การกดปุ่มเหล่านี้
จะเพิ่มหรือลดตัวเลข และอาจนำหน้าเลข 0 ออก
โปรดใช้ type="text"
แทน การดำเนินการนี้จะไม่เปลี่ยนแป้นพิมพ์บนอุปกรณ์เคลื่อนที่ให้แสดงเฉพาะตัวเลข
แต่ไม่เป็นไรเนื่องจากเคล็ดลับถัดไปสำหรับการใช้ inputmode="numeric"
จะ
ทำหน้าที่ดังกล่าว
inputmode="numeric"
ใช้ inputmode="numeric"
เพื่อเปลี่ยนแป้นพิมพ์บนอุปกรณ์เคลื่อนที่ให้แสดงเฉพาะตัวเลข
บางเว็บไซต์ใช้ type="tel"
สำหรับช่องป้อน OTP เนื่องจากจะเปลี่ยนแป้นพิมพ์บนอุปกรณ์เคลื่อนที่เป็นตัวเลขเท่านั้น (รวมถึง *
และ #
) เมื่อโฟกัส เคล็ดลับนี้ใช้ในอดีตเมื่อinputmode="numeric"
ยังไม่ได้รับการรองรับอย่างแพร่หลาย เนื่องจาก Firefox เริ่มรองรับ
inputmode="numeric"
จึงไม่จำเป็นต้องใช้แฮ็ก type="tel"
ที่ไม่ถูกต้องในเชิงความหมาย
autocomplete="one-time-code"
autocomplete
ช่วยให้นักพัฒนาแอประบุสิทธิ์ที่เบราว์เซอร์
ต้องให้ความช่วยเหลือในการเติมข้อความอัตโนมัติ และแจ้งให้เบราว์เซอร์ทราบเกี่ยวกับ
ประเภทข้อมูลที่คาดหวังในช่อง
เมื่อใดก็ตามที่ผู้ใช้ได้รับข้อความ SMS ขณะที่เปิดแบบฟอร์มอยู่ ระบบปฏิบัติการจะแยกวิเคราะห์ OTP ใน SMS โดยใช้ฮิวริสติก และแป้นพิมพ์จะแนะนำ OTP ให้ผู้ใช้ป้อนautocomplete="one-time-code"
โดยจะใช้ได้เฉพาะใน Safari 12 ขึ้นไปบน iOS, iPadOS และ macOS แต่เราขอแนะนำให้ใช้ เนื่องจากเป็นวิธีที่ดีกว่าในการปรับปรุงประสบการณ์ OTP ทาง SMS บนแพลตฟอร์มเหล่านั้น
autocomplete="one-time-code"
กำลังดำเนินการ
autocomplete="one-time-code"
ช่วยปรับปรุงประสบการณ์ของผู้ใช้ แต่คุณยังทำได้มากกว่านี้ด้วยการตรวจสอบว่าข้อความ SMS เป็นไปตามรูปแบบข้อความที่ผูกกับต้นทาง
แอตทริบิวต์ที่ไม่บังคับ
แอตทริบิวต์ที่ไม่บังคับมีดังนี้
pattern
ระบุรูปแบบที่ OTP ที่ป้อนต้องตรงกัน ใช้นิพจน์ทั่วไป เพื่อระบุรูปแบบที่ตรงกัน เช่น\d{6}
จะจำกัด OTP ให้เป็นสตริง 6 หลัก อ่านใช้ JavaScript เพื่อการตรวจสอบแบบเรียลไทม์ที่ซับซ้อนมากขึ้น เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับpattern
required
ระบุว่าผู้ใช้ต้องกรอกข้อมูลในช่อง
อ่านคำแนะนำเพิ่มเติมได้ในแนวทางปฏิบัติแนะนำเกี่ยวกับแบบฟอร์มลงชื่อเข้าใช้
จัดรูปแบบข้อความ SMS
ปรับปรุงประสบการณ์ของผู้ใช้ในการป้อน OTP โดยการปฏิบัติตามข้อกำหนดของ รหัสแบบครั้งเดียวที่ผูกกับต้นทางซึ่งส่งทาง SMS
โดยหลักการแล้ว กฎรูปแบบมีดังนี้ จบข้อความ SMS ด้วยโดเมนผู้รับที่ขึ้นต้นด้วย @
และ OTP ที่ขึ้นต้นด้วย #
เช่น
Your OTP is 123456
@web-otp.glitch.me #123456
รูปแบบมาตรฐานสำหรับข้อความ OTP ช่วยให้ดึงข้อมูลได้ง่ายและเชื่อถือได้มากขึ้น การเชื่อมโยงรหัส OTP กับเว็บไซต์จะทำให้หลอกลวงผู้ใช้ให้ป้อนรหัสในเว็บไซต์ที่เป็นอันตรายได้ยากขึ้น
กฎการจัดรูปแบบที่แม่นยำ
กฎที่แน่นอนมีดังนี้
- ข้อความจะเริ่มต้นด้วยข้อความที่มนุษย์อ่านได้ (ไม่บังคับ) ซึ่งมีสตริงอักขระที่เป็นตัวอักษรและตัวเลขคละกัน 4-10 ตัวที่มีตัวเลขอย่างน้อย 1 ตัว โดยเว้นบรรทัดสุดท้ายไว้สำหรับ URL และ OTP
- ส่วนโดเมนของ URL ของเว็บไซต์ที่เรียกใช้ API ต้องขึ้นต้นด้วย
@
- URL ต้องมี
#
ตามด้วย OTP จำนวนอักขระต้องไม่เกิน 140 ตัว
การใช้รูปแบบนี้มีประโยชน์ 2 ประการ ดังนี้
- โดย OTP จะเชื่อมโยงกับโดเมน หากผู้ใช้ใช้โดเมนอื่นที่ไม่ใช่โดเมนที่ระบุในข้อความ SMS คำแนะนำ OTP จะไม่ปรากฏ นอกจากนี้ยังช่วยลดความเสี่ยงจากการโจมตีแบบฟิชชิงและการลักลอบใช้บัญชี
- ตอนนี้เบราว์เซอร์จะสามารถดึง OTP ได้อย่างน่าเชื่อถือโดยไม่ต้องอาศัยฮิวริสติกที่ซับซ้อนและไม่แน่นอน
เมื่อเว็บไซต์ใช้ autocomplete="one-time-code"
, Safari ใน iOS 14 ขึ้นไป
จะแนะนำ OTP ตามกฎต่อไปนี้
รูปแบบข้อความ SMS นี้ยังมีประโยชน์ต่อเบราว์เซอร์อื่นๆ นอกเหนือจาก Safari ด้วย Chrome, Opera
และ Vivaldi ใน Android ยังรองรับกฎรหัสแบบใช้ครั้งเดียวที่เชื่อมโยงกับต้นทางด้วย
WebOTP API แต่ไม่รองรับผ่าน autocomplete="one-time-code"
ใช้ WebOTP API
WebOTP API ให้สิทธิ์เข้าถึง OTP
ที่ได้รับในข้อความ SMS การเรียกใช้
navigator.credentials.get()
ด้วยประเภท otp
(OTPCredential
) ที่ transport
มี sms
เว็บไซต์
จะรอ SMS ที่เป็นไปตามรหัสแบบใช้ครั้งเดียวที่ผูกกับต้นทางเพื่อ
ส่งและให้ผู้ใช้สิทธิ์เข้าถึง เมื่อส่ง OTP ไปยัง JavaScript แล้ว
เว็บไซต์จะใช้ OTP ในแบบฟอร์มหรือ POST ไปยังเซิร์ฟเวอร์โดยตรงได้
navigator.credentials.get({
otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
ดูวิธีใช้ WebOTP API โดยละเอียดได้ในยืนยันหมายเลขโทรศัพท์บนเว็บ
ด้วย WebOTP API
หรือคัดลอกและวางข้อมูลโค้ดต่อไปนี้ อย่าลืมตั้งค่าแอตทริบิวต์ action
และ method
ใน <form>
// Feature detection
if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;
// Cancel the WebOTP API if the form is submitted manually.
const ac = new AbortController();
const form = input.closest('form');
if (form) {
form.addEventListener('submit', e => {
// Cancel the WebOTP API.
ac.abort();
});
}
// Invoke the WebOTP API
navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {
input.value = otp.code;
// Automatically submit the form when an OTP is obtained.
if (form) form.submit();
}).catch(err => {
console.log(err);
});
});
}