Các phương pháp hay nhất về biểu mẫu OTP qua tin nhắn SMS

Thông thường, bạn sẽ yêu cầu người dùng cung cấp mật khẩu một lần (OTP) để xác nhận danh tính của họ bằng cách gửi tin nhắn SMS. Sau đây là một số trường hợp sử dụng OTP qua SMS:

  • Xác thực hai yếu tố. Ngoài tên người dùng và mật khẩu, bạn có thể dùng OTP qua SMS làm tín hiệu mạnh cho biết tài khoản thuộc về người nhận được OTP qua SMS.
  • Xác minh số điện thoại. Một số dịch vụ sử dụng số điện thoại làm giá trị nhận dạng chính của người dùng. Trong các dịch vụ như vậy, người dùng có thể nhập số điện thoại và OTP nhận được qua SMS để chứng minh danh tính của mình. Đôi khi, mật khẩu được kết hợp với mã PIN để tạo thành một quy trình xác thực hai yếu tố.
  • Khôi phục tài khoản. Khi người dùng mất quyền truy cập vào tài khoản của họ, cần phải có cách để khôi phục tài khoản đó. Gửi email đến địa chỉ email đã đăng ký hoặc gửi OTP qua SMS đến số điện thoại là những phương thức khôi phục tài khoản phổ biến.
  • Xác nhận thanh toán Trong hệ thống thanh toán, một số ngân hàng hoặc công ty phát hành thẻ tín dụng yêu cầu người thanh toán xác thực thêm vì lý do bảo mật. OTP qua SMS thường được dùng cho mục đích đó.

Hãy tiếp tục đọc để tìm hiểu các phương pháp hay nhất về cách tạo biểu mẫu OTP qua SMS cho những trường hợp sử dụng này.

Danh sách kiểm tra

Để mang lại trải nghiệm tốt nhất cho người dùng khi sử dụng OTP qua SMS, hãy làm theo các bước sau:

  • Sử dụng phần tử <input> với:
    • type="text"
    • inputmode="numeric"
    • autocomplete="one-time-code"
  • Sử dụng @BOUND_DOMAIN #OTP_CODE làm dòng cuối cùng của tin nhắn SMS chứa OTP.
  • Sử dụng WebOTP API.

Dùng phần tử <input>

Sử dụng biểu mẫu có phần tử <input> là phương pháp hay nhất quan trọng nhất mà bạn có thể làm theo vì phương pháp này hoạt động trong mọi trình duyệt. Ngay cả khi các đề xuất khác trong bài đăng này không hoạt động trong một số trình duyệt, người dùng vẫn có thể nhập và gửi OTP theo cách thủ công.

<form action="/verify-otp" method="POST">
  <input type="text"
      inputmode="numeric"
      autocomplete="one-time-code"
      pattern="\d{6}"
      required>
</form>

Sau đây là một số ý tưởng để đảm bảo trường nhập liệu khai thác tối đa chức năng của trình duyệt.

type="text"

Vì OTP thường là số có 5 hoặc 6 chữ số, nên việc sử dụng type="number" cho một trường nhập có vẻ trực quan vì thao tác này sẽ chỉ thay đổi bàn phím di động thành bàn phím số. Bạn không nên làm như vậy vì trình duyệt mong đợi trường nhập liệu là một số có thể đếm được chứ không phải là một chuỗi gồm nhiều số. Điều này có thể gây ra hành vi không mong muốn. Việc sử dụng type="number" sẽ khiến các nút lên và xuống xuất hiện bên cạnh trường nhập; khi nhấn các nút này, số sẽ tăng hoặc giảm và có thể xoá các số 0 đứng trước.

Thay vào đó, hãy sử dụng type="text". Thao tác này sẽ không chuyển bàn phím di động thành chỉ có số, nhưng không sao vì mẹo tiếp theo để sử dụng inputmode="numeric" sẽ làm việc đó.

inputmode="numeric"

Sử dụng inputmode="numeric" để chuyển bàn phím di động sang chế độ chỉ nhập số.

Một số trang web sử dụng type="tel" cho các trường nhập OTP vì mã này cũng chỉ chuyển bàn phím di động sang chế độ chỉ nhập số (bao gồm cả *#) khi được lấy tiêu điểm. Thủ thuật này đã được dùng trong quá khứ khi inputmode="numeric" chưa được hỗ trợ rộng rãi. Vì Firefox đã bắt đầu hỗ trợ inputmode="numeric", nên bạn không cần sử dụng giải pháp type="tel" sai về mặt ngữ nghĩa.

autocomplete="one-time-code"

Thuộc tính autocomplete cho phép nhà phát triển chỉ định quyền mà trình duyệt phải cung cấp tính năng hỗ trợ tự động hoàn thành và thông báo cho trình duyệt về loại thông tin dự kiến trong trường.

Với autocomplete="one-time-code", bất cứ khi nào người dùng nhận được tin nhắn SMS trong khi biểu mẫu đang mở, hệ điều hành sẽ phân tích cú pháp OTP trong tin nhắn SMS một cách phỏng đoán và bàn phím sẽ đề xuất OTP để người dùng nhập. Tính năng này chỉ hoạt động trên Safari 12 trở lên trên iOS, iPadOS và macOS, nhưng bạn nên sử dụng tính năng này vì đây là cách tốt hơn để cải thiện trải nghiệm OTP SMS trên những nền tảng đó.

autocomplete="one-time-code" đang hoạt động.

autocomplete="one-time-code" giúp cải thiện trải nghiệm người dùng, nhưng bạn có thể làm nhiều hơn nữa bằng cách đảm bảo rằng tin nhắn SMS tuân thủ định dạng tin nhắn ràng buộc theo nguồn.

Thuộc tính không bắt buộc

Các thuộc tính không bắt buộc bao gồm:

Hãy đọc các phương pháp hay nhất về biểu mẫu đăng nhập của chúng tôi để biết thêm lời khuyên.

Định dạng văn bản SMS

Nâng cao trải nghiệm người dùng khi nhập OTP bằng cách tuân theo quy cách mã một lần liên kết với nguồn gốc được gửi qua SMS.

Về cơ bản, quy tắc định dạng như sau: Kết thúc tin nhắn SMS bằng miền của người nhận, trước đó là @ và OTP, trước đó là #.

Ví dụ:

Your OTP is 123456

@web-otp.glitch.me #123456

Định dạng chuẩn cho tin nhắn OTP giúp việc trích xuất trở nên dễ dàng và đáng tin cậy hơn. Việc liên kết mã OTP với các trang web sẽ khiến người dùng khó bị lừa cung cấp mã cho các trang web độc hại hơn.

Quy tắc định dạng chính xác

Các quy tắc chính xác là:

  • Thông báo bắt đầu bằng văn bản (không bắt buộc) mà con người có thể đọc được, chứa một chuỗi gồm 4 đến 10 ký tự chữ và số, trong đó có ít nhất một số, để lại dòng cuối cùng cho URL và OTP.
  • Phần miền trong URL của trang web đã gọi API phải có tiền tố là @.
  • URL phải chứa #, theo sau là OTP. Số ký tự không được vượt quá 140.

Việc sử dụng định dạng này mang lại một số lợi ích:

  • OTP sẽ được liên kết với miền. Nếu người dùng đang truy cập vào các miền khác với miền được chỉ định trong tin nhắn SMS, thì đề xuất OTP sẽ không xuất hiện. Điều này cũng giúp giảm nguy cơ bị tấn công lừa đảo và nguy cơ tài khoản bị xâm nhập.
  • Giờ đây, trình duyệt có thể trích xuất mã OTP một cách đáng tin cậy mà không phụ thuộc vào các phương pháp phỏng đoán khó hiểu và không ổn định.

Khi một trang web sử dụng autocomplete="one-time-code", Safari trên iOS 14 trở lên sẽ đề xuất OTP theo các quy tắc sau.

Định dạng tin nhắn SMS này cũng mang lại lợi ích cho các trình duyệt khác ngoài Safari. Chrome, Opera và Vivaldi trên Android cũng hỗ trợ quy tắc mã sử dụng một lần liên kết với nguồn gốc bằng WebOTP API, mặc dù không thông qua autocomplete="one-time-code".

Sử dụng WebOTP API

WebOTP API cung cấp quyền truy cập vào OTP nhận được trong tin nhắn SMS. Bằng cách gọi navigator.credentials.get() bằng loại otp (OTPCredential) trong đó transport bao gồm sms, trang web sẽ đợi một SMS tuân thủ mã một lần liên kết với nguồn gốc được gửi và người dùng cấp quyền truy cập. Sau khi OTP được truyền đến JavaScript, trang web có thể sử dụng mã này trong một biểu mẫu hoặc đăng trực tiếp lên máy chủ.

navigator.credentials.get({
  otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
WebOTP API đang hoạt động.

Tìm hiểu chi tiết cách sử dụng WebOTP API trong bài viết Xác minh số điện thoại trên web bằng WebOTP API hoặc sao chép và dán đoạn mã sau. Hãy nhớ đặt thuộc tính actionmethod trong <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);
    });
  });
}