ייעול תהליך הכניסה באמצעות ממשק ה-API לניהול פרטי הכניסה

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

הגרסה האחרונה של Chrome (51) תומכת ב-Credential Management API. זוהי הצעה ב-W3C בנושא תקנים, שמעניקה למפתחים גישה פרוגרמטית למנהל פרטי הכניסה של הדפדפן ומסייעת למשתמשים להיכנס בקלות רבה יותר.

מה זה Credential Management API?

באמצעות Credential Management API, מפתחים יכולים לאחסן ולשלוף פרטי כניסה מסוג סיסמה ופרטי כניסה מאוחדים, והוא מספק 3 פונקציות:

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.requireUserMediation()

בעזרת ממשקי ה-API הפשוטים האלה, מפתחים יכולים לבצע פעולות מתקדמות כמו:

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

בהטמעה של Chrome, פרטי הכניסה יישמרו במנהל הסיסמאות של Chrome. אם המשתמשים מחוברים ל-Chrome, הם יכולים לסנכרן את הסיסמאות שלהם במכשירים השונים. אפשר גם לשתף את הסיסמאות המסונכרנות עם אפליקציות ל-Android ששילבו את Smart Lock לסיסמאות API ל-Android כדי ליהנות מחוויית שימוש חלקה בפלטפורמות שונות.

שילוב של Credential Management API באתר

האופן שבו משתמשים ב-Credential Management API באתר יכול להשתנות בהתאם לארכיטקטורה שלו. האם מדובר באפליקציה בדף יחיד? האם מדובר בארכיטקטורה מדור קודם עם מעברים בין דפים? האם טופס הכניסה נמצא רק בחלק העליון של הדף? האם לחצני הכניסה נמצאים בכל מקום? האם המשתמשים יכולים לעיין באתר שלכם בצורה משמעותית בלי להיכנס לחשבון? האם האיחוד פועל בחלונות קופצים? או האם היא דורשת אינטראקציה בכמה דפים?

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

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

באמצעות Credential Management API תוכלו להוסיף לאתר את התכונות הבאות, לדוגמה:

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

אתם יכולים לראות את התכונות האלה מוטמעות באתר הדגמה עם הקוד לדוגמה.

הצגת בורר החשבונות בזמן הכניסה

בין המגע של המשתמש בלחצן 'כניסה' לבין הניווט לטופס הכניסה, אפשר להשתמש ב-navigator.credentials.get() כדי לקבל את פרטי הכניסה. ב-Chrome יוצג ממשק משתמש לבחירת חשבון, שממנו המשתמש יוכל לבחור חשבון.

מוצג ממשק משתמש לבחירת חשבון, והמשתמש צריך לבחור חשבון לצורך כניסה.
מוצג ממשק משתמש לבחירת חשבון, והמשתמש צריך לבחור חשבון לכניסה

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

כדי להציג את פרטי הכניסה של הסיסמאות כאפשרויות לחשבון, משתמשים ב-password: true.

navigator.credentials.get({
    password: true, // `true` to obtain password credentials
}).then(function(cred) {
    // continuation
    ...

כניסה באמצעות פרטי כניסה עם סיסמה

אחרי שהמשתמש יבחר חשבון, פונקציית הפתרון תקבל פרטי כניסה עם סיסמה. אפשר לשלוח אותו לשרת באמצעות fetch():

    // continued from previous example
}).then(function(cred) {
    if (cred) {
    if (cred.type == 'password') {
        // Construct FormData object
        var form = new FormData();

        // Append CSRF Token
        var csrf_token = document.querySelector('csrf_token').value;
        form.append('csrf_token', csrf_token);

        // You can append additional credential data to `.additionalData`
        cred.additionalData = form;

        // `POST` the credential object as `credentials`.
        // id, password and the additional data will be encoded and
        // sent to the url as the HTTP body.
        fetch(url, {           // Make sure the URL is HTTPS
        method: 'POST',      // Use POST
        credentials: cred    // Add the password credential object
        }).then(function() {
        // continuation
        });
    } else if (cred.type == 'federated') {
        // continuation

כניסה באמצעות פרטי כניסה מאוחדים

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

כשיש כמה חשבונות שמאוחסנים במנהל הסיסמאות.
כשיש כמה חשבונות שמאוחסנים במנהל הסיסמאות
navigator.credentials.get({
    password: true, // `true` to obtain password credentials
    federated: {
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    }
}).then(function(cred) {
    // continuation
    ...

אפשר לבדוק את המאפיין type של אובייקט פרטי הכניסה כדי לראות אם הוא PasswordCredential (type == 'password') או FederatedCredential (type == 'federated'). אם פרטי הכניסה הם FederatedCredential, אפשר לבצע קריאה ל-API המתאים באמצעות המידע שהם מכילים.

    });
} else if (cred.type == 'federated') {
    // `provider` contains the identity provider string
    switch (cred.provider) {
    case 'https://accounts.google.com':
        // Federated login using Google Sign-In
        var auth2 = gapi.auth2.getAuthInstance();

        // In Google Sign-In library, you can specify an account.
        // Attempt to sign in with by using `login_hint`.
        return auth2.signIn({
        login_hint: cred.id || ''
        }).then(function(profile) {
        // continuation
        });
        break;

    case 'https://www.facebook.com':
        // Federated login using Facebook Login
        // continuation
        break;

    default:
        // show form
        break;
    }
}
// if the credential is `undefined`
} else {
// show form
תרשים זרימה של ניהול פרטי הכניסה.

אחסון פרטי הכניסה

כשמשתמש נכנס לאתר באמצעות טופס, אפשר להשתמש ב-navigator.credentials.store() כדי לשמור את פרטי הכניסה. המשתמש יתבקש לאחסן את התמונה או לא. בהתאם לסוג פרטי הכניסה, משתמשים ב-new PasswordCredential() או ב-new FederatedCredential() כדי ליצור אובייקט של פרטי הכניסה שרוצים לאחסן.

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

יצירת פרטי כניסה מסיסמה ושמירתם מרכיב טופס

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

HTML html <form id="form" method="post"> <input type="text" name="id" autocomplete="username" /> <input type="password" name="password" autocomplete="current-password" /> <input type="hidden" name="csrf_token" value="******" /> </form>

JavaScript

var form = document.querySelector('\#form');
var cred = new PasswordCredential(form);
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});

יצירה ואחסון של פרטי כניסה מאוחד

// After a federation, create a FederatedCredential object using
// information you have obtained
var cred = new FederatedCredential({
    id: id,                                  // The id for the user
    name: name,                              // Optional user name
    provider: 'https://accounts.google.com',  // A string that represents the identity provider
    iconURL: iconUrl                         // Optional user avatar image url
});
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});
תרשים של תהליך הכניסה לחשבון.

לאפשר למשתמש להיכנס שוב באופן אוטומטי

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

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

אחזור אובייקט פרטי כניסה

navigator.credentials.get({
    password: true, // Obtain password credentials or not
    federated: {    // Obtain federation credentials or not
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    },
    unmediated: true // `unmediated: true` lets the user automatically sign in
}).then(function(cred) {
    if (cred) {
    // auto sign-in possible
    ...
    } else {
    // auto sign-in not possible
    ...
    }
});

הקוד אמור להיראות דומה לקוד שראיתם בקטע 'הצגת חלונית לבחירת חשבון בזמן הכניסה'. ההבדל היחיד הוא שתגדירו את הערך של unmediated: true.

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

  • המשתמש אישר את התכונה 'כניסה אוטומטית' בהודעת פתיחה חמה.
  • המשתמש נכנס בעבר לאתר באמצעות Credential Management API.
  • למשתמש יש רק פרטי כניסה אחד שמאוחסנים במקור שלכם.
  • המשתמש לא יצא מהחשבון באופן מפורש בסשן הקודם.

אם אחד מהתנאים האלה לא יתקיים, הפונקציה תידחה.

דיאגרמת תהליך של אובייקט פרטי כניסה

תהליך בחירת חשבון לכניסה אוטומטית

כשמשתמש יוצא מהחשבון באתר שלכם, אתם אחראים לוודא שהמשתמש לא ייכנס שוב באופן אוטומטי. כדי לוודא זאת, Credential Management API מספק מנגנון שנקרא בחירת רשת. כדי להפעיל את מצב בחירת הרשת, צריך להפעיל את הפונקציה navigator.credentials.requireUserMediation(). כל עוד סטטוס בחירת הרשת של המשתמש למקור מופעל, השימוש ב-unmediated: true עם navigator.credentials.get() יביא לפתרון הפונקציה עם הערך undefined.

תהליך בחירת חשבון לכניסה אוטומטית

navigator.credentials.requireUserMediation();
תרשים זרימה של כניסה אוטומטית.

שאלות נפוצות

האם JavaScript באתר יכול לאחזר סיסמה גולמית? לא. אפשר לקבל סיסמאות רק כחלק מ-PasswordCredential, ואי אפשר לחשוף אותן בשום צורה.

האם אפשר לאחסן 3 קבוצות של ספרות למזהה באמצעות Credential Management API? לא כרגע. נשמח לקבל ממך משוב על המפרט.

האם אפשר להשתמש ב-Credential Management API בתוך iframe? ה-API מוגבל להקשרים ברמה העליונה. קריאות ל-.get() או ל-.store() ב-iframe יישלחו באופן מיידי ללא השפעה.

האם אפשר לשלב את תוסף Chrome לניהול סיסמאות עם Credential Management API? אפשר לשנות את navigator.credentials ולקשר אותו לתוסף של Chrome כדי להשתמש בפרטי הכניסה של get() או store().

משאבים

מידע נוסף על Credential Management API זמין במדריך השילוב.