שיטות מומלצות לטופס OTP באמצעות SMS

כדאי לקרוא איך לבצע אופטימיזציה של טופס ה-SMS ל-OTP ולשפר את חוויית המשתמש.

אחת הדרכים הנפוצות לאימות מספר הטלפון של משתמש היא לבקש ממנו לספק את ה-OTP (הסיסמה החד-פעמית) שנשלחת ב-SMS. יש כמה תרחישים לדוגמה לשימוש ב-OTP ב-SMS:

  • אימות דו-שלבי בנוסף לשם המשתמש ולסיסמה, אפשר להשתמש ב-OTP ל-SMS כאות חזק לכך שהחשבון שייך לאדם שקיבל את ה-OTP ל-SMS.
  • אימות מספר הטלפון. בחלק מהשירותים, מספר הטלפון משמש כמזהה הראשי של המשתמש. בשירותים כאלה, המשתמשים יכולים להזין את מספר הטלפון ואת קוד האימות החד-פעמי (OTP) שקיבלו ב-SMS כדי להוכיח את הזהות שלהם. לפעמים הוא משולב עם מספר PIN כדי ליצור אימות דו-שלבי.
  • שחזור חשבון אם משתמש מאבד את הגישה לחשבון, צריכה להיות לו אפשרות לשחזר אותו. שליחת אימייל לכתובת האימייל הרשומה או שליחת SMS חד-פעמי למספר הטלפון שלהם היא שיטה נפוצה לשחזור החשבון.
  • אישור תשלום: במערכות תשלומים, חלק מהבנקים או מנפיקי כרטיסי האשראי מבקשים מהמשלם אימות נוסף מטעמי אבטחה. לשם כך, משתמשים בדרך כלל ב-SMS OTP.

במאמר הזה מפורטות שיטות מומלצות ליצירת טופס OTP ל-SMS לתרחישים לדוגמה שצוינו למעלה.

רשימת המשימות

כדי לספק את חוויית המשתמש הטובה ביותר עם OTP ב-SMS, יש לפעול לפי השלבים הבאים:

  • משתמשים ברכיב <input> עם:
    • type="text"
    • inputmode="numeric"
    • autocomplete="one-time-code"
  • משתמשים ב-@BOUND_DOMAIN #OTP_CODE כשורה האחרונה של הודעת ה-SMS עם קוד האימות החד-פעמי.
  • משתמשים ב-WebOTP API.

שימוש ברכיב <input>

השיטה המומלצת החשובה ביותר היא להשתמש בטופס עם רכיב <input>, כי הוא פועל בכל הדפדפנים. גם אם ההצעות האחרות במאמר הזה לא יפעלו בדפדפן מסוים, המשתמש עדיין יוכל להזין את קוד האימות החד-פעמי ולשלוח אותו באופן ידני.

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

בהמשך מפורטים כמה רעיונות שיעזרו לכם להפיק את המקסימום מהפונקציונליות של הדפדפן בשדה להזנת קלט.

type="text"

מכיוון שקודי חד-פעמיים הם בדרך כלל מספרים בני חמש או שש ספרות, השימוש ב-type="number" בשדה להזנת קלט עשוי להיראות אינטואיטיבי כי הוא משנה את המקלדת בנייד למספרים בלבד. לא מומלץ לעשות זאת כי הדפדפן מצפה ששדה קלט יהיה מספר שניתן לספור ולא רצף של מספרים מרובים, דבר שעלול לגרום להתנהגות בלתי צפויה. כשמשתמשים ב-type="number", מוצגים לחצני למעלה ולמטה לצד שדה הקלט. לחיצה על הלחצנים האלה מגדילה או מקטינה את המספר, ועשויה להסיר אפסים שקדמו לו.

במקום זאת, אתם צריכים להשתמש ב-type="text". הפעולה הזו לא תהפוך את המקלדת בנייד למקלדת של מספרים בלבד, אבל זה בסדר כי הטיפים הבאים לשימוש ב-inputmode="numeric" עושים את זה.

inputmode="numeric"

מקישים על inputmode="numeric" כדי לשנות את המקלדת לספרות בלבד.

באתרים מסוימים משתמשים ב-type="tel" לשדות להזנת קלט של OTP, כי הוא גם הופך את המקלדת בנייד למספרים בלבד (כולל * ו-#) כשמתמקדים. הטריק הזה שימש בעבר כשלא הייתה תמיכה רחבה ב-inputmode="numeric". מאחר שFirefox התחיל לתמוך ב-inputmode="numeric", אין צורך להשתמש בהאק type="tel" שגוי מבחינה סמנטית.

autocomplete="one-time-code"

האטריבוט autocomplete מאפשר למפתחים לציין את ההרשאה של הדפדפן לספק עזרה בהשלמה האוטומטית, ומעדכן את הדפדפן לגבי סוג המידע הצפוי בשדה.

כשמשתמשים ב-autocomplete="one-time-code", בכל פעם שמשתמש מקבל הודעת SMS בזמן שהטופס פתוח, מערכת ההפעלה תנתח את קוד האימות החד-פעמי ב-SMS באופן היוריסטי והמקלדת תציע למשתמש להזין את קוד האימות החד-פעמי. התכונה פועלת רק ב-Safari מגרסה 12 ואילך ב-iOS, ב-iPadOS וב-macOS, אבל מומלץ מאוד להשתמש בה כי היא דרך קלה לשפר את חוויית השימוש ב-OTP ב-SMS בפלטפורמות האלה.

`autocomplete="one-time-code"` בפעולה.

autocomplete="one-time-code" משפרת את חוויית המשתמש, אבל אפשר לעשות עוד דברים על ידי הבטחת התאימות של הודעת ה-SMS לפורמט ההודעה המקושר למקור.

עיצוב הטקסט של הודעת ה-SMS

שיפור חוויית המשתמש בהזנת OTP באמצעות התאמה למפרט של הקודים החד-פעמיים המשויכים למקור שהועברו באמצעות SMS.

הכלל של הפורמט הוא פשוט: מסיימים את הודעת ה-SMS עם דומיין הנמען שלפניו מופיע @ וה-OTP שלפניו הוא #.

לדוגמה:

Your OTP is 123456

@web-otp.glitch.me #123456

כשמשתמשים בפורמט סטנדרטי להודעות OTP, אפשר לחלץ קודים בקלות ובצורה מהימנה יותר. שיוך קודי OTP לאתרים מקשה על המשתמשים לספק קוד לאתרים זדוניים.

לשימוש בפורמט הזה יש כמה יתרונות:

  • ה-OTP יהיה קשור לדומיין. אם המשתמש נמצא בדומיינים שונים מהדומיין שצוין בהודעת ה-SMS, ההצעה ל-OTP לא תופיע. כך גם מפחיתים את הסיכון למתקפות פישינג ולפריצות אפשריות לחשבון.
  • הדפדפן יוכל עכשיו לחלץ את ה-OTP באופן מהימן, בלי להסתמך על שיטות ניתוח נתונים סתריות ופגיעות.

כשאתר משתמש ב-autocomplete="one-time-code", דפדפן Safari עם iOS מגרסה 14 ואילך יציע את קוד האימות החד-פעמי בהתאם לכללים שלמעלה.

פורמט ההודעות ב-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, אפשר להשתמש בו בטופס באתר או לשלוח אותו ישירות לשרת באמצעות POST.

navigator.credentials.get({
  otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
WebOTP API בפעולה.

אפשר לקרוא מידע מפורט על השימוש ב-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);
    });
  });
}

תמונה מאת Jason Leung ב-Unsplash.