אימות מספרי טלפון באינטרנט באמצעות WebOTP API

עזרה למשתמשים עם קודי אימות חד-פעמיים (OTP) שהתקבלו ב-SMS

מהו WebOTP API?

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

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

הרעיון הזה כבר מופעל בתרחישים רבים כדי להשיג את היעדים הבאים:

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

התהליך הנוכחי יוצר חיכוך אצל המשתמשים. חיפוש קוד אימות חד-פעמי בהודעת SMS, העתקה והדבקה שלו בטופס הוא תהליך מסורבל, שעלול להוריד את שיעורי ההמרה בתהליכי שימוש קריטיים. הרבה מפתחים ברחבי העולם ביקשו במשך זמן רב לפשט את התהליך הזה באינטרנט. ל-Android יש API שמאפשר לעשות בדיוק את זה. כך גם iOS ו-Safari.

באמצעות WebOTP API, האפליקציה יכולה לקבל הודעות בפורמט מיוחד שמקושרות לדומיין של האפליקציה. כך תוכלו לקבל OTP באופן פרוגרמטי מהודעת SMS ולאמת מספר טלפון של משתמש בקלות רבה יותר.

ראו הדגמה

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

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

התהליך כולו מוצג בתרשים שבהמשך.

תרשים של 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 מורכב משלושה חלקים:

  • תג <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

ממשק ה-API של WebOTP עצמו פשוט למדי. משתמשים ב-navigator.credentials.get() כדי לקבל את הסיסמה החד-פעמית. 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(). לבסוף, ההודעה צריכה לעמוד בפורמט הבא:

  • ההודעה מתחילה בטקסט (אופציונלי) שאפשר לקרוא אותו, שמכיל מחרוזת אלפאנומרית בת ארבע עד עשר אותיות, עם לפחות מספר אחד, והשורה האחרונה מיועדת לכתובת ה-URL ול-OTP.
  • החלק של הדומיין בכתובת ה-URL של האתר שהפעיל את ה-API חייב להתחיל ב-@.
  • כתובת ה-URL חייבת להכיל סימן לירה (#) ואחריו את קוד האימות החד-פעמי.

לדוגמה:

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
צפוי רווח בודד בין @host לבין #code.
Your verification code is 123456

@example.com  #123456
צפוי רווח בודד בין @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 חוצה-מקורות

הקלדה של OTP ב-SMS ב-iframe ממקורות שונים משמשת בדרך כלל לאישור תשלום, במיוחד עם 3D Secure. הפורמט המשותף תומך ברכיבי iframe ממקורות שונים, ולכן WebOTP API מספק מפתחות OTP שמקושרים למקורות בתצוגת עץ. לדוגמה:

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

כדי להשתמש ב-WebOTP API מתוך iframe ממקורות שונים, צריך לבצע שני דברים:

  • מוסיפים הערות גם למקור של המסגרת העליונה וגם למקור של ה-iframe בהודעת הטקסט ב-SMS.
  • מגדירים את מדיניות ההרשאות כך שאפשר יהיה לקבל OTP ישירות מהמשתמש ב-iframe שמקורו במקור אחר.
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, כדי למנוע התנהגות לא מכוונת. באופן כללי, יש שתי דרכים להשיג את היעד הזה:

דרך כותרת 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 למחשב וגם ב-Chrome ל-Android.

כל מה שמפתחים צריכים לעשות הוא להטמיע את WebOTP API באתר למחשבים, באותו אופן שבו הם מטמיעים אותו באתר לנייד, אבל אין צורך בטריקים מיוחדים.

מידע נוסף זמין במאמר אימות מספר טלפון במחשב באמצעות WebOTP API.

שאלות נפוצות

תיבת הדו-שיח לא מופיעה למרות שאני שולח הודעה בפורמט תקין. מה הבעיה?

יש כמה דברים שחשוב לזכור כשבודקים את ה-API:

  • אם מספר הטלפון של השולח נכלל ברשימת אנשי הקשר של הנמען, ה-API הזה לא יופעל בגלל העיצוב של SMS User Consent API (ממשק ה-API הבסיסי לקבלת הסכמה מהמשתמשים לשימוש ב-SMS).
  • אם אתם משתמשים בפרופיל עבודה במכשיר 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 שימושי לאימות מספר טלפון כשהוא מסופק בפעם הראשונה, אבל צריך להשתמש באימות מספר טלפון ב-SMS בזהירות לצורך אימות חוזר, כי ספקי הסלולר יכולים לחטוף מספרי טלפון ולהשתמש בהם שוב. WebOTP הוא מנגנון נוח לאימות מחדש ולשחזור, אבל שירותים צריכים לשלב אותו עם גורמים נוספים, כמו בדיקת ידע, או להשתמש ב-Web Authentication API לאימות חזק.

איפה אפשר לדווח על באגים בהטמעה ב-Chrome?

מצאתם באג בהטמעה של Chrome?

  • שולחים דיווח על באג ב-crbug.com. חשוב לכלול כמה שיותר פרטים, הוראות פשוטות לשחזור הבעיה ולהגדיר את Components ל-Blink>WebOTP.

איך אפשר לעזור לשפר את התכונה הזו?

מתכננים להשתמש ב-WebOTP API? התמיכה הציבורית שלכם עוזרת לנו לקבוע את סדר העדיפויות של התכונות, ומראה ליצרני דפדפנים אחרים כמה חשובה התמיכה בהן. שולחים ציוץ אל @ChromiumDev עם ההאשטאג #WebOTP ומציינים איפה ואיך אתם משתמשים בו.

משאבים