ספריית ה-JavaScript של google.accounts.oauth2
עוזרת להציג הצעות למשתמשים
הסכמה ולקבל אסימון גישה כדי לעבוד עם נתוני משתמשים. היא מבוססת
תהליך הענקת גישה משתמעת ב-OAuth 2.0, שנועד לאפשר לכם לקרוא ל-Google
ממשקי API שמשתמשים ישירות ב-REST ו-CORS, או כדי להשתמש בספריית הלקוח של Google APIs
JavaScript (שנקרא גם gapi.client
) לגישה פשוטה וגמישה
ממשקי API מורכבים יותר.
לפני שהמשתמשים ניגשים לנתוני משתמש מוגנים מדפדפן, המשתמשים באתר מפעילים הכלי של Google לבחירת חשבונות, תהליכי כניסה והסכמה, ולבסוף בעיה בשרתי ה-OAuth של Google ומחזירה אסימון גישה לאפליקציית האינטרנט שלך.
במודל ההרשאה המבוסס על אסימון, אין צורך לאחסן לכל משתמש אסימוני רענון בשרת העורפי.
מומלץ לפעול לפי הגישה שמתוארת כאן במקום שיטות שמפורטות בגרסה הישנה יותר של OAuth 2.0 לאפליקציות אינטרנט בצד הלקוח מותאמת אישית.
הגדרה
כדי למצוא או ליצור מזהה לקוח, פועלים לפי השלבים שמתוארים במאמר קבלת
מדריך בנושא מזהה הלקוח ב-Google API. בשלב הבא, מוסיפים את ספריית הלקוח לדפים
באתר שלכם שיקרא ל-Google APIs. לבסוף, מאתחלים את האסימון
הלקוח. בדרך כלל, הפעולה הזו מתבצעת בתוך ה-handler של onload
בספריית הלקוח.
אתחול לקוח אסימונים
צריך לקרוא אל initTokenClient()
כדי לאתחל לקוח אסימון חדש ב-
מזהה לקוח, אם רוצים, אפשר לכלול רשימה של היקף אחד או יותר
צריך גישה ל:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (response) => {
...
},
});
הפעלת זרימת אסימון OAuth 2.0
משתמשים ב-method requestAccessToken()
כדי להפעיל את האסימון של חוויית המשתמש ולקבל
אסימון גישה. Google מבקשת מהמשתמש:
- בוחרים את החשבון שלהם,
- להיכנס לחשבון Google, אם עדיין לא נכנסתם אליו,
- להעניק הסכמה לאפליקציית האינטרנט שלך לגשת לכל היקף מבוקש.
תנועת משתמש מפעילה את זרימת האסימון: <button onclick="client.requestAccessToken();">Authorize me</button>
לאחר מכן Google מחזירה TokenResponse
שמכיל אסימון גישה ורשימה של
היקפי ההרשאות שהמשתמש העניק להם גישה, או שגיאה, ל-handler של הקריאה החוזרת.
המשתמשים יכולים לסגור את בורר החשבונות או את חלונות הכניסה, במקרה כזה פונקציית הקריאה החוזרת לא תופעל.
איך לטפל בהסכמה
יש להטמיע את העיצוב וחוויית המשתמש של האפליקציה רק אחרי בדיקה יסודית של מדיניות OAuth 2.0 של Google. כללי המדיניות האלה כוללים עבודה לפי כמה היקפים, מתי ואיך לטפל בהסכמת המשתמשים ועוד.
הרשאה מצטברת היא מתודולוגיה של מדיניות ותכנון אפליקציות שמשמשת כדי לבקש גישה למשאבים תוך שימוש בהיקפים, רק לפי הצורך ולא מראש וכל זה בבת אחת. המשתמשים יכולים לאשר או לדחות את השיתוף של המשאבים הספציפיים שמבקשת האפליקציה שלכם, נקראת הרשאות מפורטות.
במהלך התהליך הזה Google מבקשת את הסכמת המשתמש, ומפרטת בנפרד היקף המבוקש, המשתמשים בוחרים את המשאבים שישותפו עם האפליקציה, ולבסוף, Google מפעילה את פונקציית הקריאה החוזרת כדי להחזיר אסימון גישה ומשתמש להיקפים שאושרו. לאחר מכן האפליקציה תטפל בבטחה בתוצאות השונות השונות באמצעות הרשאות מפורטות.
הרשאה מצטברת
לגבי אפליקציות אינטרנט, שני התרחישים הכלליים הבאים מדגימים באמצעות:
- אפליקציית Ajax בדף יחיד, המשתמשת לעיתים קרובות ב-
XMLHttpRequest
עם גישה דינמית אל במשאבי אנוש. - דפי אינטרנט מרובים, משאבים מופרדים ומנוהלים על בסיס דף יחיד.
שני התרחישים האלה מוצגים כדי להדגים שיקולי עיצוב מבוססות-מתודולוגיות, אך הן לא נועדו לספק המלצות מקיפות בנוגע לאופן שבו כדי לפתח הסכמה באפליקציה. אפליקציות בעולם האמיתי עשויות להשתמש בווריאציה או שילוב של הטכניקות האלה.
Ajax
אפשר להוסיף תמיכה להרשאה מצטברת לאפליקציה על ידי ביצוע מספר שיחות
אל requestAccessToken()
ומשתמשים באובייקט OverridableTokenClientConfig
scope
לבקשת היקפים נפרדים בזמן שיש בהם צורך.
רק במקרה הצורך. בדוגמה הזו יישלחו בקשות למשאבים והם יהיו גלויים
רק אחרי שתנועת המשתמש מרחיבה קטע תוכן מכווץ.
אפליקציית Ajax |
---|
מאתחלים את לקוח האסימון בעת טעינת הדף:
const client = google.accounts.oauth2.initTokenClient({ client_id: 'YOUR_GOOGLE_CLIENT_ID', callback: "onTokenResponse", }); מסמכים לקריאההצגת המסמכים האחרונים client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/documents.readonly' }) ); אירועים בזמן הקרובהצגת פרטי היומן client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/calendar.readonly' }) ); קרוסלת תמונותהצגת תמונות client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/photoslibrary.readonly' }) ); |
כל שיחה אל requestAccessToken
מפעילה רגע שבו המשתמש הביע הסכמה, האפליקציה שלך
להיות בעלי גישה רק למשאבים הנדרשים על פי הקטע שהמשתמש בוחר
כך שהוא מגביל את שיתוף המשאבים באמצעות בחירת המשתמש.
דפי אינטרנט מרובים
כשמתכננים הרשאה מצטברת, דפים מרובים משמשים לשליחת בקשה רק את ההיקפים הנדרשים לטעינת דף, מה שמקטין את המורכבות ואת הצורך ביצוע קריאות מרובות כדי לקבל הסכמה מהמשתמשים ולאחזר אסימון גישה.
אפליקציה עם מספר דפים | ||||||||
---|---|---|---|---|---|---|---|---|
|
כל דף מבקש את ההיקף הנדרש ומקבל אסימון גישה באמצעות קריאה
initTokenClient()
ו-requestAccessToken()
בזמן הטעינה. במקרה הזה,
דפי אינטרנט נפרדים משמשים להפרדה ברורה בין הפונקציונליות של המשתמשים
משאבים לפי היקף. במצב בעולם האמיתי, דפים מסוימים עשויים לבקש
כמה היקפים קשורים.
הרשאות מפורטות
הרשאות מפורטות מטופלות באותו אופן בכל התרחישים; אחרי
הפקודה requestAccessToken()
מפעילה את פונקציית הקריאה החוזרת ואסימון גישה
הוחזרו, ודאו שהמשתמש אישר את היקפי ההרשאות המבוקשים באמצעות
hasGrantedAllScopes()
או hasGrantedAnyScope()
. לדוגמה:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly \
https://www.googleapis.com/auth/documents.readonly \
https://www.googleapis.com/auth/photoslibrary.readonly',
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
'https://www.googleapis.com/auth/photoslibrary.readonly')) {
// Look at pictures
...
}
if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
'https://www.googleapis.com/auth/calendar.readonly',
'https://www.googleapis.com/auth/documents.readonly')) {
// Meeting planning and review documents
...
}
}
},
});
גם מענקים שהתקבלו בעבר מסשנים או מבקשות קודמות
כלולה בתשובה. נשמרת תיעוד של הסכמת המשתמש לכל משתמש, וכן
Client-ID, שנשמר בקריאות מרובות אל initTokenClient()
או
requestAccessToken()
. כברירת מחדל, הסכמת המשתמש נחוצה רק
בכל פעם שמשתמש מבקר באתר שלכם ומבקש היקף חדש, אבל ייתכן שהוא יתבקש
בכל טעינת דף באמצעות prompt=consent
באובייקטים של הגדרת לקוח Token Client.
עבודה עם אסימונים
במודל האסימון, אסימון גישה לא מאוחסן על ידי מערכת ההפעלה או הדפדפן, אלא על ידי הדפדפן.
אסימון חדש מתקבל לראשונה בזמן טעינת הדף, או לאחר מכן על ידי הפעלת
קריאה ל-requestAccessToken()
באמצעות תנועת משתמש כמו לחיצה על לחצן.
שימוש ב-REST וב-CORS עם Google APIs
אפשר להשתמש באסימון גישה כדי לשלוח בקשות מאומתות ל-Google APIs באמצעות REST ו-CORS. כך המשתמשים יכולים להיכנס, להעניק הסכמה, ל-Google להנפיק כדי לעבוד עם נתוני המשתמש.
בדוגמה הזו, אפשר לראות את האירועים הקרובים ביומן של משתמשים מחוברים באמצעות
אסימון הגישה שהחזיר tokenRequest()
:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();
מידע נוסף זמין במאמר איך להשתמש ב-CORS כדי לגשת ל-Google APIs.
בקטע הבא מוסבר איך לשלב בקלות עם ממשקי API מורכבים יותר.
עבודה עם ספריית JavaScript של Google APIs
לקוח האסימון פועל עם ספריית הלקוח של Google API ל-JavaScript קטע הקוד מופיע בהמשך.
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
gapi.client.setApiKey('YOUR_API_KEY');
gapi.client.load('calendar', 'v3', listUpcomingEvents);
}
},
});
function listUpcomingEvents() {
gapi.client.calendar.events.list(...);
}
תפוגת האסימון
לאסימוני גישה יש תוחלת חיים קצרה. אם תוקף אסימון הגישה פג
לפני סוף הסשן של המשתמש, צריך לקבל אסימון חדש באמצעות קריאה
requestAccessToken()
מאירוע שנוצר על ידי משתמש, כמו לחיצה על לחצן.
שימוש באסימון גישה כדי לבטל את ההסכמה
מפעילים את השיטה google.accounts.oauth2.revoke
כדי להסיר את הסכמת המשתמש.
גישה למשאבים בכל היקפי ההרשאות שהוענקו לאפליקציה שלך. גישה חוקית
יש צורך באסימון כדי לבטל את ההרשאה הזו:
google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
console.log(done);
console.log(done.successful);
console.log(done.error);
console.log(done.error_description);
});