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

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

Chrome 57

ב-Chrome 57 הוסיפה השינוי החשוב הזה Credential Management API.

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

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

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

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

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

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

Chrome 60

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

נדרשת התייחסות לזיהוי התכונה

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

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

אובייקט אחד (PasswordCredential) כולל עכשיו סיסמה

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

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

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

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

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

ה-Credential Management 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(), השם של ה-method 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? יש לנו מסמך במדריך להעברת נתונים (מיגרציה) שניתן לעקוב אחריהם כדי לשדרג לגרסה החדשה.