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