ליצור תהליך כניסה באמצעות מפתחות גישה, תוך התאמה למשתמשי סיסמאות קיימים.
מפתחות גישה מחליפים את הסיסמאות והופכים את חשבונות המשתמשים באינטרנט לבטוחים, פשוטים וקלים יותר לשימוש. אבל המעבר מאימות מבוסס-סיסמה לאימות מבוסס מפתחות גישה עלול לסבך את חוויית המשתמש. השימוש במילוי אוטומטי של טפסים כדי להציע מפתחות גישה יכול לעזור לכם ליצור חוויה מאוחדת.
למה כדאי להשתמש במילוי אוטומטי של טפסים כדי להיכנס לחשבון באמצעות מפתח גישה?
עם מפתח גישה, משתמשים יכולים להיכנס לאתר באמצעות טביעת אצבע, זיהוי פנים או קוד אימות של המכשיר.
במצב אידיאלי לא יהיו משתמשים בסיסמאות, ותהליך האימות יכול להיות פשוט כמו לחצן כניסה אחד. כשהמשתמש מקיש על הלחצן, קופצת תיבת דו-שיח של בורר חשבונות, שבה המשתמש יכול לבחור חשבון, לבטל את נעילת המסך כדי לאמת את החשבון ולהיכנס אליו.
אבל המעבר מסיסמה לאימות שמבוסס על מפתחות גישה עשוי להיות מאתגר. כשמשתמשים עוברים למפתחות גישה, עדיין יהיו מי שישתמשו בסיסמאות ובאתרים שלא יצטרכו לספק מענה לשני סוגי המשתמשים. חשוב להקפיד שהמשתמשים לא יזכרו באילו אתרים הם עברו למפתחות גישה, לכן אם תבקשו מהמשתמשים לבחור באיזו שיטה להשתמש מראש, חוויית השימוש תהיה גרועה.
מפתחות הגישה הם גם טכנולוגיה חדשה. הסבר על האלמנטים האלה והקפדה על כך שהמשתמשים יוכלו להרגיש בנוח להשתמש בהם יכולים להיות אתגר לבעלי האתרים. אנחנו יכולים להסתמך על חוויית משתמש מוכרת למילוי אוטומטי של סיסמאות כדי לפתור את שתי הבעיות.
ממשק משתמש מותנה
כדי לספק חוויית שימוש יעילה למשתמשים עם מפתחות גישה ולסיסמאות, אתם יכולים לכלול מפתחות גישה בהצעות למילוי אוטומטי. הוא נקרא ממשק משתמש מותנה והוא חלק מתקן WebAuthn.
ברגע שהמשתמש יקיש על שדה הקלט של שם המשתמש, קופצת תיבת דו-שיח עם הצעות למילוי אוטומטי, שמדגישה את מפתחות הגישה השמורים יחד עם ההצעות למילוי אוטומטי של הסיסמאות. לאחר מכן המשתמש יכול לבחור חשבון ולהשתמש בנעילת המסך של המכשיר כדי להיכנס.
כך משתמשים יוכלו להיכנס לאתר באמצעות הטופס הקיים כאילו שום דבר לא השתנה, אבל עם היתרון הנוסף של האבטחה של מפתחות גישה, אם יש להם כזה.
איך זה עובד
כדי לבצע אימות באמצעות מפתח גישה, צריך להשתמש ב-WebAuthn API.
ארבעת הרכיבים בתהליך אימות של מפתחות גישה הם: המשתמש:
- הקצה העורפי: שרת העורפי שמכיל את מסד הנתונים של החשבונות שבו נשמר המפתח הציבורי ומטא-נתונים נוספים לגבי מפתח הגישה.
- הקצה הקדמי: הקצה הקדמי שלכם מתקשר עם הדפדפן ושולח בקשות שליפה לקצה העורפי.
- דפדפן: הדפדפן של המשתמש שמריץ את JavaScript.
- מאמת חשבונות: מאמת החשבונות של המשתמש שיוצר ומאחסן את מפתח הגישה. המכשיר עשוי להיות באותו מכשיר שבו נמצא הדפדפן (למשל, כשמשתמשים ב-Windows Hello) או במכשיר אחר, כמו טלפון.
![תרשים אימות של מפתחות גישה](https://web.dev/static/articles/passkey-form-autofill/image/passkey-authentication-diagram.png?authuser=5&hl=he)
- ברגע שמשתמש מגיע בקצה העורפי, הוא מבקש מהקצה העורפי לבצע אימות באמצעות מפתח גישה וקורא ל-
navigator.credentials.get()
להתחיל אימות באמצעות מפתח גישה. הפעולה הזו מחזירהPromise
. - כשהמשתמש שם את הסמן בשדה הכניסה, בדפדפן מוצגת תיבת דו-שיח למילוי אוטומטי של סיסמאות, כולל מפתחות גישה. תופיע תיבת דו-שיח לאימות אם המשתמש יבחר מפתח גישה.
- אחרי שהמשתמש יאמת את הזהות שלו באמצעות נעילת המסך של המכשיר, ההבטחה תטופל ופרטי הכניסה למפתח הציבורי יוחזרו לממשק הקצה.
- הקצה הקדמי שולח את פרטי הכניסה של המפתח הציבורי לקצה העורפי. הקצה העורפי מאמת את החתימה מול המפתח הציבורי של החשבון התואם במסד הנתונים. אם הפעולה מצליחה, המשתמש ייכנס לחשבון.
אימות באמצעות מפתח גישה באמצעות מילוי אוטומטי של טפסים
כשמשתמש רוצה להיכנס לחשבון, אתם יכולים לבצע קריאה מותנית ל-get
של WebAuthn כדי לציין שמפתחות הגישה יכולים להיכלל בהצעות למילוי אוטומטי. קריאה מותנית ל-API navigator.credentials.get()
של WebAuthn לא מוצגת בממשק המשתמש ונשארת בהמתנה עד שהמשתמש יבחר חשבון לכניסה באמצעות ההצעות למילוי אוטומטי. אם המשתמש יבחר מפתח גישה, הדפדפן יאשר את ההבטחה באמצעות פרטי כניסה, במקום למלא את טופס הכניסה. אם כך, הדף אחראי להכניס את המשתמש לחשבון.
הוספת הערות לשדה להזנת קלט בטופס
מוסיפים מאפיין autocomplete
לשדה של שם המשתמש input
, אם צריך.
צריך לצרף את username
ואת webauthn
כאסימונים כדי לאפשר לו להציע מפתחות גישה.
<input type="text" name="username" autocomplete="username webauthn" ...>
זיהוי תכונות
לפני שמפעילים קריאה מותנית ל-WebAuthn API, צריך לבדוק אם:
- הדפדפן תומך ב-WebAuthn עם
PublicKeyCredential
.
- הדפדפן תומך בממשק משתמש מותנה של WebAuthn עם
PublicKeyCredenital.isConditionalMediationAvailable()
.
// Availability of `window.PublicKeyCredential` means WebAuthn is usable.
if (window.PublicKeyCredential &&
PublicKeyCredential.isConditionalMediationAvailable) {
// Check if conditional mediation is available.
const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
if (isCMA) {
// Call WebAuthn authentication
}
}
אחזור אתגר משרת RP
אחזור אתגר משרת RP שנדרש כדי לקרוא ל-navigator.credentials.get()
:
challenge
: אתגר שנוצר על ידי שרת ב-ArrayBuffer. הפעולה הזו נדרשת כדי למנוע התקפות שליחה מחדש. חשוב ליצור אתגר חדש בכל ניסיון כניסה ומתעלמים ממנו אחרי פרק זמן מסוים או אחרי שהאימות של ניסיון כניסה נכשל. זה כמו אסימון CSRF.allowCredentials
: מערך של פרטי כניסה קבילים לאימות הזה. מעבירים מערך ריק כדי לאפשר למשתמש לבחור מפתח גישה זמין מהרשימה המוצגת בדפדפן.userVerification
: מציינת אם אימות המשתמש באמצעות נעילת המסך של המכשיר הוא"required"
,"preferred"
או"discouraged"
. ברירת המחדל היא"preferred"
, והמאמת יכול לדלג על אימות המשתמש. צריך להגדיר את הערך הזה כ-"preferred"
או להשמיט את הנכס.
קוראים ל-WebAuthn API עם הדגל conditional
כדי לאמת את המשתמש
אפשר להתקשר אל navigator.credentials.get()
כדי להתחיל להמתין לאימות המשתמש.
// To abort a WebAuthn call, instantiate an `AbortController`.
const abortController = new AbortController();
const publicKeyCredentialRequestOptions = {
// Server generated challenge
challenge: ****,
// The same RP ID as used during registration
rpId: 'example.com',
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
rpId
: מזהה RP הוא דומיין והאתר יכול לציין את הדומיין שלו או סיומת שאפשר לרשום. הערך הזה צריך להתאים למזהה ה-rp.id שבו נעשה שימוש כשמפתח הגישה נוצר.
חשוב לציין את mediation: 'conditional'
כדי שהבקשה תהיה מותנית.
שליחת פרטי הכניסה של המפתח הציבורי שהוחזרו לשרת ה-RP
אחרי שהמשתמש בוחר חשבון ומסכים באמצעות נעילת המסך של המכשיר, ההבטחה מחזירה אובייקט PublicKeyCredential
לממשק ה-RP.
הבטחה יכולה להידחות מכמה סיבות. צריך לטפל בשגיאות בהתאם, בהתאם למאפיין name
של האובייקט Error
:
NotAllowedError
: המשתמש ביטל את הפעולה.- חריגים אחרים: קרה משהו בלתי צפוי. הדפדפן מציג למשתמש תיבת דו-שיח עם שגיאה.
האובייקט של פרטי הכניסה של המפתח הציבורי מכיל את המאפיינים הבאים:
id
: המזהה בקידוד base64 URL של פרטי הכניסה המאומתים של מפתח הגישה.rawId
: גרסת ArrayBuffer של מזהה פרטי הכניסה.response.clientDataJSON
: ArrayBuffer של נתוני לקוח. השדה הזה מכיל מידע כמו האתגר והמקור ששרת ה-RP יצטרך לאמת.response.authenticatorData
: ArrayBuffer של נתונים ממאמת החשבונות. השדה הזה מכיל מידע כמו מזהה הגורם המוגבל.response.signature
: ArrayBuffer של החתימה. הערך הזה הוא הליבה של פרטי הכניסה וצריך לאמת אותו בשרת.response.userHandle
: ArrayBuffer שכלל את מזהה המשתמש שהוגדר בזמן היצירה. אפשר להשתמש בערך הזה במקום במזהה של פרטי הכניסה אם השרת צריך לבחור את ערכי המזהים שהוא משתמש בו, או אם הקצה העורפי מעוניין להימנע מיצירת אינדקס במזהים של פרטי כניסה.authenticatorAttachment
: מחזירplatform
כשפרטי הכניסה הגיעו מהמכשיר המקומי. אחרת,cross-platform
, במיוחד אם המשתמש השתמש בטלפון כדי להיכנס. אם המשתמש צריך להשתמש בטלפון כדי להיכנס לחשבון, כדאי לבקש ממנו ליצור מפתח גישה במכשיר המקומי.type
: השדה הזה תמיד מוגדר ל-"public-key"
.
אם אתם משתמשים בספרייה כדי לטפל באובייקט של פרטי הכניסה של המפתח הציבורי בשרת RP, מומלץ לשלוח את האובייקט כולו לשרת אחרי שהוא מקודד באופן חלקי באמצעות base64url.
אימות החתימה
כשמקבלים את פרטי הכניסה של המפתח הציבורי בשרת, מעבירים אותם לספריית FIDO כדי לעבד את האובייקט.
מחפשים את המזהה התואם של פרטי הכניסה באמצעות המאפיין id
(אם אתם צריכים לזהות את חשבון המשתמש, תוכלו להשתמש במאפיין userHandle
שהוא user.id
שציינתם כשיצרתם את פרטי הכניסה). בודקים אם אפשר לאמת את signature
של פרטי הכניסה באמצעות המפתח הציבורי שמאוחסן. כדי לעשות זאת, מומלץ להשתמש בספרייה בצד השרת או בפתרון במקום לכתוב קוד משלכם. תוכלו למצוא ספריות קוד פתוח במאגר GitHub המדהים של Webauth.
אחרי שפרטי הכניסה מאומתים באמצעות מפתח ציבורי תואם, מכניסים את המשתמש לחשבון.
הוראות מפורטות יותר מפורטות במאמר אימות מפתח גישה בצד השרת.