העדכונים האחרונים ב-API לניהול פרטי הכניסה

חלק מהעדכונים שמפורטים כאן מוסברים בסשן Google I/O, כניסה מאובטחת ותהליך קל: שמירה על התעניינות המשתמשים:

Chrome 57

השינויים החשובים האלה הוכנסו ל-Credential Management API ב-Chrome 57.

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

מעכשיו, Chrome יכול לאחזר פרטי כניסה שמאוחסנים בתת-דומיין אחר באמצעות Credential Management API. לדוגמה, אם סיסמה מאוחסנת ב-login.example.com, סקריפט ב-www.example.com יכול להציג אותה כאחד מפריטי החשבון בתיבת הדו-שיח לבחירת חשבון.

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

אחרי שהסיסמה מאוחסנת, היא זמינה כפרטי כניסה באותו מקור www.example.com ואילך.

בצילום המסך הבא, פרטי הכניסה ששמורים ב-login.aliexpress.com גלויים ל-m.aliexpress.com וזמינים למשתמש לבחירה:

בורר החשבונות שבו מוצגים פרטי הכניסה שנבחרו לתת-הדומיין

Chrome 60

ב-Chrome 60 נוספו כמה שינויים חשובים ב-Credential Management API:

נדרשת התייחסות לזיהוי המאפיינים

כדי לבדוק אם ממשק ה-API לניהול פרטי כניסה זמין לגישה לפרטי כניסה מבוססי סיסמה ולפרטי כניסה מאוחדים, צריך לבדוק אם window.PasswordCredential או window.FederatedCredential זמינים.

if (window.PasswordCredential || window.FederatedCredential) {
  // The Credential Management API is available
}

האובייקט PasswordCredential כולל עכשיו סיסמה

ב-Credential Management API ננקטה גישה שמרנית לטיפול בסיסמה. הוא הסתיר את הסיסמאות מ-JavaScript, והמפתחים נדרשו לשלוח את האובייקט PasswordCredential ישירות לשרת שלהם לצורך אימות באמצעות תוסף ל-fetch() API.

אבל הגישה הזו הובילה למספר הגבלות. קיבלנו משוב על כך שמפתחים לא הצליחו להשתמש ב-API כי:

  • הם נאלצו לשלוח את הסיסמה כחלק מאובייקט JSON.

  • הם נאלצו לשלוח את ערך הגיבוב של הסיסמה לשרת שלהם.

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

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

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(passwordCred => {
    if (passwordCred) {
    let form = new FormData();
    form.append('email', passwordCred.id);
    form.append('password', passwordCred.password);
    form.append('csrf_token', csrf_token);
    return fetch('/signin', {
        method: 'POST',
        credentials: 'include',
        body: form
    });
    } else {

    // Fallback to sign-in form
    }
}).then(res => {
    if (res.status === 200) {
    return res.json();
    } else {
    throw 'Auth failed';
    }
}).then(profile => {
    console.log('Auth succeeded', profile);
});

אחזור מותאם אישית יוצא משימוש בקרוב

כדי לקבוע אם אתם משתמשים בפונקציה מותאמת אישית של fetch(), בודקים אם היא משתמשת באובייקט PasswordCredential או באובייקט FederatedCredential בתור ערך של מאפיין credentials. לדוגמה:

fetch('/signin', {
    method: 'POST',
    credentials: c
})

מומלץ להשתמש בפונקציה רגילה של fetch() כפי שמוצג בדוגמת הקוד הקודמת, או להשתמש ב-XMLHttpRequest.

עד גרסה 60 של Chrome, המאפיין navigator.credentials.get() קיבל מאפיין unmediated אופציונלי עם דגל בוליאני. לדוגמה:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    unmediated: true
}).then(c => {

    // Sign-in
});

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

הדגל מורחב עכשיו כבחירת רשת. בחירת הרשת של המשתמש יכולה להתרחש במקרים הבאים:

  • המשתמש צריך לבחור חשבון להתחברות.

  • משתמש רוצה להיכנס לחשבון באופן מפורש אחרי קריאה ל-navigator.credentials.requireUseMediation().

בוחרים אחת מהאפשרויות הבאות לערך mediation:

ערך של mediation בהשוואה לדגל בוליאני התנהגות
silent שווה ל-unmediated: true פרטי הכניסה הועברו בלי להציג חלונית לבחירת חשבון.
optional שווה ל-unmediated: false הצגת בורר חשבונות אם preventSilentAccess() הופעל בעבר.
required אפשרות חדשה תמיד להציג בורר חשבונות. האפשרות הזו שימושית כשרוצים לאפשר למשתמש לעבור חשבון באמצעות תיבת הדו-שיח המובנית לבחירת חשבון.

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

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(c => {

    // Sign-in
});

השם של requireUserMediation() השתנה ל-preventSilentAccess()

כדי להתאים את השיטה לנכס mediation החדש שמוצג בקריאה get(), שינינו את השם של השיטה navigator.credentials.requireUserMediation() ל-navigator.credentials.preventSilentAccess().

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

signoutUser();
if (navigator.credentials) {
    navigator.credentials.preventSilentAccess();
}

יצירת אובייקטים של פרטי כניסה באופן אסינכרוני באמצעות השיטה החדשה navigator.credentials.create()

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

יצירת אובייקט PasswordCredential

הגישה לסנכרון
let c = new PasswordCredential(form);
גישה אסינכרונית (חדש)
let c = await navigator.credentials.create({
    password: form
});

או:

let c = await navigator.credentials.create({
    password: {
    id: id,
    password: password
    }
});

יצירת אובייקט FederatedCredential

הגישה לסנכרון
let c = new FederatedCredential({
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
});
גישה אסינכרונית (חדש)
let c = await navigator.credentials.create({
    federated: {
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
    }
});

מדריך להעברת נתונים (מיגרציה)

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