איך יצרנו את הכרטיסייה WebAuthn ל-Chrome DevTools

Fawaz Mohammad
Fawaz Mohammad
Nina Satragno
Nina Satragno

Web Authentication API, שנקרא גם WebAuthn, מאפשר לשרתים להשתמש בקריפטוגרפיה של מפתח ציבורי – במקום בסיסמאות – כדי לרשום משתמשים ולאמת אותם. היא עושה זאת על ידי הפעלת אינטגרציה בין השרתים האלה לבין מאמתי אימות חזקים. מאמתי החשבונות יכולים להיות מכשירים פיזיים ייעודיים (למשל מפתחות אבטחה) או שמשולבים עם פלטפורמות (למשל קוראי טביעות אצבע). כאן אפשר לקרוא מידע נוסף על WebAuthn בכתובת webauthn.guide.

הבעיות של המפתחים

לפני הפרויקט הזה, לא הייתה ב-WebAuthn תמיכה מובנית בניפוי באגים ב-Chrome. מפַתח שפיתח אפליקציה שמשתמשת ב-WebAuth צריך גישה למאמתים פיזיים. הדבר היה קשה במיוחד משתי סיבות:

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

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

רצינו לפשט את התהליך והוספנו תמיכה בניפוי באגים ישירות בכלי הפיתוח ל-Chrome.

הפתרון: כרטיסיית WebAuthn חדשה

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

כרטיסיית WebAuthn חדשה

הטמעה

הוספת התמיכה בניפוי באגים ל-WebAuthn הייתה תהליך דו-שלבי.

תהליך בשני חלקים

חלק 1: הוספת דומיין WebAuthn לפרוטוקול כלי הפיתוח ל-Chrome

קודם כול, הטמענו דומיין חדש בפרוטוקול Chrome DevTools (CDP), שמחובר ל-handler שמקשר עם הקצה העורפי WebAuthn.

ה-CDP מחבר בין הקצה הקדמי של כלי הפיתוח ל-Chromium. במקרה שלנו, השתמשנו בפעולות הדומיין WebAuthn כדי לגשר בין הכרטיסייה WebAuthn DevTools לבין ההטמעה של WebAuthn ב-Chromium.

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

אנחנו גם חושפים שיטות בדומיין שמשמשות כשכבה דקה לממשקים הקיימים של 'מאמת חשבונות וירטואלי' ו'גילוי וירטואלי', שהם חלק מההטמעה של WebAuthn ב-Chromium. השיטות האלה כוללות הוספה והסרה של מאמתים, וגם יצירה, קבלה וניקוי של פרטי הכניסה הרשומים שלהם.

(צריך לקרוא את הקוד)

חלק 2: יצירת הכרטיסייה שגלויה למשתמשים

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

למרות שנדרשים 3 רכיבים נדרשים, אנחנו צריכים לדאוג רק לשניים מהם: המודל והתצוגה המפורטת. הרכיב השלישי – סוכן, נוצר באופן אוטומטי אחרי הוספת הדומיין. בקצרה, הסוכן הוא השכבה שמבצעת את הקריאות בין ממשק הקצה לבין ה-CDP.

המודל

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

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

(צריך לקרוא את הקוד)

התצוגה

כרטיסיית WebAuthn חדשה

אנחנו משתמשים בתצוגה כדי לספק את ממשק המשתמש שהמפתח יכול למצוא כשהוא ניגשים לכלי הפיתוח. היא מכילה:

  1. סרגל כלים להפעלה של סביבת מאמת וירטואלי.
  2. קטע להוספה של מאמתים.
  3. קטע ייעודי למאמתים שנוצרו.

(צריך לקרוא את הקוד)

סרגל הכלים כדי להפעיל סביבה של מאמת וירטואלי

סרגל הכלים

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

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

החלטנו ששינוי מצב מפורש מוביל לחוויית משתמש טובה יותר, במיוחד למשתמשים שנכנסים לכרטיסייה WebAuthn מבלי לצפות שגילוי נאות אמיתי יושבת.

הוספת הקטע 'מאמתי חשבונות'

הוספת הקטע 'מאמתי חשבונות'

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

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

התצוגה 'מאמת חשבונות'

התצוגה 'מאמת חשבונות'

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

השם של מאמת החשבונות

ניתן להתאים אישית את שם מאמת החשבונות, וברירת המחדל שלו היא 'מאמת חשבונות' משורשר ל-5 התווים האחרונים של המזהה. במקור, שם מאמת החשבונות היה המזהה המלא שלו ולא ניתן לשנות אותו. יישמנו שמות שניתן להתאים אישית כדי שהמשתמש יוכל להוסיף תווית למאמת החשבונות על סמך היכולות שלו, המאמת הפיזי שהוא נועד לחקות, או כל כינוי שקצת יותר קל להבנה ממזהה באורך 36 תווים.

טבלת פרטי כניסה

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

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

הלחצן 'פעיל'

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

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

אתגר מעניין שהיה לנו בעת הוספת הלחצן הפעיל היה להימנע ממרוץ תהליכים. למשל, נבחן את התרחיש הבא:

  1. המשתמש לוחץ על לחצן הבחירה פעיל עבור מאמת החשבונות X, ושולח בקשה ל-CDP להגדרת X כפעיל. לחצן הבחירה פעיל של X נבחר וכל שאר האפשרויות לא מסומנות.

  2. מיד לאחר מכן, המשתמש לוחץ על לחצן הבחירה Active עבור מאמת החשבונות Y ושולח בקשה ל-CDP להגדיר את Y כפעיל. לחצן הבחירה פעיל של Y נבחר. כל שאר הערכים, כולל X, לא מסומנים.

  3. בקצה העורפי, הקריאה להגדרת Y כפעיל מסתיימת ונפתרה. Y פעיל עכשיו וכל שאר האימותים לא פעילים.

  4. בקצה העורפי, הקריאה להגדרת X כפעיל מסתיימת ונפתרה. X פעיל עכשיו וכל שאר האימותים, כולל Y, לא פעילים.

עכשיו התוצאה היא: X הוא מאמת החשבונות הפעיל. עם זאת, לחצן הבחירה פעיל של X לא נבחר. לא המאמת הפעיל. עם זאת, לחצן הבחירה Active של Y כן נבחר. יש מחלוקת בין ממשק הקצה לבין הסטטוס בפועל של מאמתי החשבונות. כמובן שזו בעיה.

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

כך זה נראה:


 async _setActiveAuthenticator(authenticatorId) {
   await this._clearActiveAuthenticator();
   await this._model.setAutomaticPresenceSimulation(authenticatorId, true);
   this._activeId = authenticatorId;
   this._updateActiveButtons();
 }
 
 _updateActiveButtons() {
   const authenticators = this._authenticatorsView.getElementsByClassName('authenticator-section');
   Array.from(authenticators).forEach(authenticator => {
     authenticator.querySelector('input.dt-radio-button').checked =
         authenticator.getAttribute('data-authenticator-id') === this._activeId;
   });
 }
 
 async _clearActiveAuthenticator() {
   if (this._activeId) {
     await this._model.setAutomaticPresenceSimulation(this._activeId, false);
   }
   this._activeId = null;
 }

מדדי שימוש

רצינו לעקוב אחרי השימוש בתכונה הזו. בהתחלה היו לנו שתי אפשרויות.

  1. ספירה בכל פעם שהכרטיסייה WebAuthn נפתחה בכלי הפיתוח. האפשרות הזאת עלולה לגרום לספירת יתר, כי מישהו עלול לפתוח את הכרטיסייה בלי להשתמש בה בפועל.

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

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

סיכום

תודה על הקריאה! אם יש לכם הצעות לשיפור הכרטיסייה WebAuthn, תוכלו להודיע לנו על ידי שליחת באג.

לפניכם כמה מקורות מידע שיעזרו לכם לקבל מידע נוסף על WebAuthn:

הורדת הערוצים של התצוגה המקדימה

כדאי להשתמש ב-Chrome Canary, Dev או בטא כדפדפן הפיתוח שמוגדר כברירת מחדל. הערוצים לתצוגה מקדימה אלה מעניקים לך גישה לתכונות החדשות של כלי הפיתוח, בודקים ממשקי API מתקדמים של פלטפורמות אינטרנט ומוצאים בעיות באתר שלך לפני שהמשתמשים עושים זאת.

יצירת קשר עם הצוות של כלי הפיתוח ל-Chrome

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

  • אפשר לשלוח לנו הצעה או משוב דרך crbug.com.
  • כדי לדווח על בעיה בכלי הפיתוח, לוחצים על אפשרויות נוספות   עוד > עזרה > דיווח על בעיות בכלי הפיתוח ב'כלי פיתוח'.
  • שליחת ציוץ אל @ChromeDevTools.
  • נשמח לשמוע מה חדש בסרטונים ב-YouTube של כלי הפיתוח או בסרטונים ב-YouTube שקשורים לכלי פיתוח.