סקירה כללית
כדי לקבל אסימון גישה לכל משתמש עבור קריאות ל-Google APIs, Google מציעה מספר ספריות JavaScript:
המדריך הזה מספק הוראות להעברה מהספריות האלה לספרייה של שירותי Google Identity.
המדריך הזה יעזור לך:
- להחליף את ספריית הפלטפורמה שהוצאה משימוש ואת ספריית שירותי הזהויות, וגם
- אם אתם משתמשים בספריית לקוח ה-API, הסירו את המודול
gapi.auth2
שהוצא משימוש ואת השיטות והאובייקטים שלו והחליפו אותם בשווה ערך ב-Services Services.
כדי להבין מה השתנה בספריית JavaScript של שירותי Identity, כדאי לקרוא את הסקירה הכללית ואת הסבר על הרשאת המשתמשים כדי לסקור מונחים ומושגים מרכזיים.
אם אתם מחפשים אימות להרשמה ולכניסה של המשתמשים, אפשר לעיין במאמר מעבר מכניסה באמצעות חשבון Google.
זיהוי זרימת ההרשאות שלך
קיימים שני תהליכי אישור משתמשים אפשריים: קוד מרומז וקוד הרשאה.
לבדוק את אפליקציית האינטרנט שלכם כדי לזהות את סוג תהליך ההרשאה שנמצא כרגע בשימוש.
סימנים שאפליקציית האינטרנט שלכם משתמשת בהם בתהליך המשתמע:
- אפליקציית האינטרנט שלך מבוססת דפדפן בלבד, ללא פלטפורמה בקצה העורפי.
- המשתמש חייב להיות נוכח כדי לבצע קריאה ל-Google APIs, האפליקציה משתמשת באסימוני גישה בלבד, ואינה דורשת אסימוני רענון.
- אפליקציית האינטרנט שלך טוענת את
apis.google.com/js/api.js
. - ההטמעה מבוססת על OAuth 2.0 לאפליקציות אינטרנט בצד הלקוח.
- האפליקציה שלכם משתמשת במודולים
gapi.client
אוgapi.auth2
שנמצאים בספריית הלקוחות של Google API ל-JavaScript.
אינדיקטורים שאפליקציית האינטרנט משתמשת בתהליך קוד ההרשאה:
ההטמעה מבוססת על:
האפליקציה שלכם פועלת גם בדפדפן של המשתמש, וגם בפלטפורמת הקצה העורפי.
פלטפורמת הקצה העורפי מארחת נקודת קצה (endpoint) של קוד הרשאה.
הפלטפורמה לקצה העורפי קוראת ל-Google APIs מטעם משתמשים, ללא צורך בנוכחותם. הם נקראים גם מצב אופליין.
אסימוני רענון מנוהלים ומאוחסנים על ידי הפלטפורמה לקצה העורפי.
במקרים מסוימים, ייתכן שבסיס הנתונים שלכם תומך בשני התהליכים.
בחירה בתהליך הרשאה
לפני שתתחילו את המעבר, תצטרכו להחליט אם אתם ממשיכים בתהליך הנוכחי או משתמשים בזרימה אחרת שמתאימה לצרכים שלכם.
חשוב לקרוא את הבחירת תהליך הרשאות כדי להבין מה ההבדל העיקרי בין שני התהליכים.
ברוב המקרים, התהליך של קוד ההרשאה מומלץ כי הוא מספק את רמת האבטחה הגבוהה ביותר של המשתמש. הטמעת התהליך מאפשרת לפלטפורמה להוסיף בקלות פונקציונליות אופליין חדשה, כמו אחזור עדכונים, כדי לעדכן את המשתמשים בשינויים חשובים ביומן, בתמונות, במינויים וכו'.
בוחרים תהליך הרשאה באמצעות הבוררים שלמטה.
זרם הענקת גישה משתמע
קבלת אסימון גישה לשימוש בדפדפן כשהמשתמש נוכח.
בדוגמאות משתמעות לזרימה ניתן לראות אפליקציות אינטרנט לפני ואחרי העברתן לשירותי זהויות.
תהליך קוד הרשאה
קוד הרשאה לכל משתמש שמונפק על ידי Google נשלח לפלטפורמת הקצה העורפי, ואז הוא מועבר לאסימון גישה ולאסימון רענון.
דוגמאות לזרימה של קוד הרשאה הצגת אפליקציות אינטרנט לפני ואחרי העברתן לשירותי זהויות.
במדריך הזה, פועלים לפי ההוראות המפורטות בהדגשה, הוספה, הסרה, עדכון או החלפה של הפונקציונליות הקיימת.
שינויים באפליקציית האינטרנט בדפדפן
בקטע הזה מתוארים השינויים שתבצעו באפליקציית האינטרנט בדפדפן, כשתעברו לספריית JavaScript של שירותי Google Identity.
זיהוי הקוד והבדיקה שהושפעו
קובץ cookie לניפוי באגים יכול לעזור לכם לאתר את הקוד שהושפע ולבדוק את ההתנהגות לאחר ההוצאה משימוש.
באפליקציות גדולות או מורכבות, יכול להיות שיהיה קשה למצוא את כל הקודים שהושפעו מההוצאה משימוש של המודול gapi.auth2
. כדי לתעד במסוף את השימוש הקיים בפונקציונליות שהוצאה משימוש בקרוב, מגדירים את הערך של קובץ ה-cookie מסוג G_AUTH2_MIGRATION
לערך informational
. אתם יכולים גם להוסיף נקודתיים ואחריה ערך מרכזי כדי להתחבר לאחסון בסשן.
אחרי שנכנסים לחשבון ומקבלים את פרטי הכניסה, בודקים או שולחים את היומנים שנאספו לקצה העורפי לצורך ניתוח במועד מאוחר יותר. לדוגמה, הפונקציה informational:showauth2use
שומרת את המקור ואת כתובת ה-URL במפתח אחסון לסשן בשם showauth2use
.
כדי לאמת את התנהגות האפליקציה כשהמודול gapi.auth2
לא נטען יותר, צריך להגדיר את הערך של קובץ ה-cookie G_AUTH2_MIGRATION
לערך enforced
. כך ניתן לבדוק את ההתנהגות של הוצאה משימוש לפני תאריך האכיפה.
ערכים אפשריים של קובץ cookie מסוג G_AUTH2_MIGRATION
:
enforced
אין לטעון את המודולgapi.auth2
.informational
תיעוד ביומן של פונקציונליות שהוצאה משימוש למסוף JS. בנוסף, יש להתחבר לאחסון של הסשן כשמוגדר שם מפתח אופציונלי:informational:key-name
.
כדי למזער את השפעת המשתמש, מומלץ להגדיר את קובץ ה-cookie באופן מקומי במהלך הפיתוח והבדיקה, לפני שמשתמשים בו בסביבות ייצור.
ספריות ומודולים
המודול gapi.auth2
מנהל אימות משתמשים לצורך כניסה לחשבון והזרם המשתמע של הרשאה, החלפת המודול שהוצא משימוש והאובייקטים והשיטות שלו בספרייה של Google Identity Services.
מוסיפים את הספרייה של שירותי הזהות לאפליקציית האינטרנט על ידי הכללתה במסמך:
<script src="https://accounts.google.com/gsi/client" async defer></script>
מסירים את כל המופעים של טעינת המודול auth2
באמצעות gapi.load('auth2', function)
.
הספרייה של Google Identity Services מחליפה את השימוש במודול gapi.auth2
.
תוכלו להמשיך להשתמש במודול gapi.client
מתוך ספריית הלקוחות של Google API ל-JavaScript, וליהנות מהיתרונות של יצירה אוטומטית של שיטות JS שאפשר להתקשר אליהן ממסמך Discovery, יצירת קריאות מרובות ל-API ופונקציונליות של ניהול CORS.
קובצי cookie
הרשאת המשתמש אינה דורשת שימוש בקובצי cookie.
במאמרים העברה מכניסה באמצעות חשבון Google מוסבר איך אימות המשתמשים משתמש בקובצי cookie, ובמאמר איך Google משתמשת בקובצי cookie למידע על השימוש בקובצי cookie על ידי מוצרים ושירותים אחרים של Google.
פרטי כניסה
שירותי הזהויות מופרדים על ידי אימות המשתמשים וההרשאות לשתי פעולות נפרדות, ופרטי הכניסה של המשתמשים נפרדים: אסימון המזהה שמשמש לזיהוי המשתמש מוחזר בנפרד מאסימון הגישה המשמש להרשאה.
תוכלו להיעזר בפרטי הכניסה לדוגמה כדי לראות את השינויים האלה.
זרם הענקת גישה משתמע
תוכלו להסיר בנפרד את האימות וההרשאה של המשתמש על ידי הסרת הטיפול בתהליכי מתן ההרשאות.
מסירים את הפניות הלקוחות האלה לכניסה אל JavaScript ב-Google:
שיטות
GoogleUser.getBasicProfile()
GoogleUser.getId()
תהליך קוד הרשאה
שירותי הזהויות מפרידים בין פרטי הכניסה בדפדפן לאסימון המזהה ולאסימון הגישה. השינוי הזה לא חל על פרטי כניסה שמתקבלים באמצעות קריאות ישירות לנקודות הקצה של Google OAuth 2.0 מפלטפורמת הקצה העורפי, או דרך ספריות שפועלות בשרת מאובטח בפלטפורמה כמו לקוח Node.js של Google APIs.
מצב הסשן
בעבר, התכונה 'כניסה באמצעות חשבון Google' עזרה לכם לנהל את הסטטוס של כניסות של משתמשים באמצעות:
- handlers לקריאה חוזרת (callback) למעקב אחרי מצב הסשן של המשתמש.
- מאזינים לאירועים ושינויים בסטטוס 'מחובר' לחשבון Google של משתמש.
אתם אחראים לנהל את מצב הכניסה ואת הסשנים של המשתמשים באפליקציית האינטרנט.
מסירים את הפניות הלקוחות האלה לכניסה אל JavaScript ב-Google:
אובייקטים:
gapi.auth2.SignInOptions
שיטות:
GoogleAuth.attachClickHandler()
GoogleAuth.isSignedIn()
GoogleAuth.isSignedIn.get()
GoogleAuth.isSignedIn.listen()
GoogleAuth.signIn()
GoogleAuth.signOut()
GoogleAuth.currentUser.get()
GoogleAuth.currentUser.listen()
GoogleUser.isSignedIn()
הגדרת לקוח
עדכנו את אפליקציית האינטרנט שלכם כדי להפעיל לקוח אסימון בתהליך ההענקת גישה המרומז או ההרשאה.
מסירים את הפניות הלקוחות האלה לכניסה אל JavaScript ב-Google:
אובייקטים:
gapi.auth2.ClientConfig
gapi.auth2.OfflineAccessOptions
שיטות:
gapi.auth2.getAuthInstance()
GoogleUser.grant()
זרם הענקת גישה משתמע
כדי להוסיף את אפליקציית האינטרנט צריך להוסיף אובייקט TokenClientConfig
וקריאה ל-initTokenClient()
לפי הדוגמה שבקטע אתחול של לקוח אסימון.
החלפת הפניות של לקוחות ב-JavaScript לכניסה באמצעות חשבון Google בשירותי Google Identity:
אובייקטים:
gapi.auth2.AuthorizeConfig
עםTokenClientConfig
שיטות:
gapi.auth2.init()
עםgoogle.accounts.oauth2.initTokenClient()
פרמטרים:
gapi.auth2.AuthorizeConfig.login_hint
עםTokenClientConfig.hint
.gapi.auth2.GoogleUser.getHostedDomain()
עםTokenClientConfig.hosted_domain
.
תהליך קוד הרשאה
כדי להגדיר את אפליקציית האינטרנט, מוסיפים אובייקט CodeClientConfig
וקריאה ל-initCodeClient()
לפי הדוגמה שבאתחול של לקוח קוד.
כשעוברים מהמשתמע לזרימה של קוד ההרשאה:
הסרה הפניות לקוח של כניסה באמצעות חשבון Google
אובייקטים:
gapi.auth2.AuthorizeConfig
שיטות:
gapi.auth2.init()
פרמטרים:
gapi.auth2.AuthorizeConfig.login_hint
gapi.auth2.GoogleUser.getHostedDomain()
בקשה לאסימון
תנועה של משתמש, כמו לחיצה על לחצן, יוצרת בקשה שמובילה להחזיר אסימון גישה ישירות לדפדפן של המשתמש באמצעות התהליך המשתמע, או אל הפלטפורמה לקצה העורפי לאחר החלפת קוד הרשאה למשתמש עבור אסימון גישה ואסימון רענון.
זרם הענקת גישה משתמע
אפשר לקבל אסימוני גישה ולהשתמש בהם בדפדפן, כל עוד הוא מחובר לחשבון ויש לו סשן פעיל עם Google. להענקת גישה משתמעת, נדרשת תנועת משתמש כדי לבקש אסימון גישה, גם אם נשלחה בעבר בקשה.
החלפה הפניות של לקוחות ב-Google לכניסה לחשבון ב-JavaScript: בשירותי Google Identity:
שיטות:
gapi.auth2.authorize()
עםTokenClient.requestAccessToken()
GoogleUser.reloadAuthResponse()
עםTokenClient.requestAccessToken()
אפשר להוסיף קישור או לחצן כדי להתקשר למספר requestAccessToken()
ולהפעיל את החלון הקופץ של חוויית המשתמש כדי לבקש אסימון גישה, או כדי לקבל אסימון חדש כשתוקפו של האסימון הקיים יפוג.
מעדכנים את בסיס הקוד כדי:
- הפעלת תהליך האימות של OAuth 2.0
עם
requestAccessToken()
. - תמיכה בהרשאה מצטברת באמצעות שימוש ב-
requestAccessToken
וב-OverridableTokenClientConfig
להפרדת בקשה אחת להיקפים רבים בבקשות מרובות קטנות יותר. - יש לבקש אסימון חדש כשתוקף האסימון הקיים יפוג או אם יבוטל.
עבודה עם היקפים מרובים עשויה לחייב שינויים מבניים בבסיס הקודים כדי לבקש גישה להיקפים רק אם הם זקוקים להם ולא כולם בבת אחת. כל בקשה צריכה לכלול כמה שיותר היקפים, ובאופן אידיאלי, בהיקף יחיד. תוכלו לקרוא איך לטפל בהסכמת משתמשים בקישור הזה.
כשיפוג התוקף של אסימון גישה, המודול gapi.auth2
מקבל באופן אוטומטי אסימון גישה חדש וחוקי לאפליקציית האינטרנט שלכם. לשיפור אבטחת המשתמשים, תהליך הרענון האוטומטי של אסימון לא נתמך על ידי הספרייה של שירותי Google Identity. עליכם לעדכן את אפליקציית האינטרנט כדי לזהות אסימון גישה שפג תוקפו ולבקש אסימון חדש. מידע נוסף מפורט בקטע 'טיפול באסימונים' שבהמשך.
תהליך קוד הרשאה
הוסיפו קישור או לחצן כדי להתקשר אל requestCode()
ולבקש קוד הרשאה מ-Google. לדוגמה, עיינו במאמר הפעלת זרימת קוד OAuth 2.0.
בקטע 'טיפול באסימון' שבהמשך מוסבר איך מגיבים לאסימון גישה שפג תוקפו או מבוטל.
טיפול באסימונים
טיפול בשגיאות הוספה כדי לזהות קריאות שנכשלו ב-Google API כשנעשה שימוש באסימון גישה שפג תוקפו או בוטל, ולבקש אסימון גישה חדש וחוקי.
קוד מצב HTTP של הודעת השגיאה 401 Unauthorized
ו-invalid_token
מוחזר על ידי Google APIs כשנעשה שימוש באסימון גישה שפג תוקפו או שבוטל. לדוגמה, קראו את המאמר תגובה לא חוקית לאסימון.
אסימונים שפג תוקפם
אסימוני גישה הם לטווח קצר, ובדרך כלל תקפים למשך מספר דקות בלבד.
ביטול אסימונים
בכל שלב, בעל חשבון Google יכול לבטל הסכמה שניתנה בעבר.
פעולה זו מבטלת את התוקף של אסימוני גישה קיימים ושל אסימוני רענון. אפשר לבטל את הפלטפורמה באמצעות revoke()
או באמצעות חשבון Google.
החלפה הפניות של לקוחות ב-Google לכניסה לחשבון ב-JavaScript: בשירותי Google Identity:
שיטות:
getAuthInstance().disconnect()
עםgoogle.accounts.oauth2.revoke()
GoogleUser.disconnect()
עםgoogle.accounts.oauth2.revoke()
כשמשתמש revoke
מוחק את החשבון שלו מהפלטפורמה או רוצה להסיר את הסכמתו לשיתוף נתונים עם האפליקציה שלכם.
בקשה לקבלת הסכמה מהמשתמשים
Google מציגה למשתמש תיבת דו-שיח להבעת הסכמה כשאפליקציית האינטרנט או פלטפורמת הקצה העורפי מבקשים אסימון גישה. דוגמאות לתיבות דו-שיח להבעת הסכמה ש-Google מציגה למשתמשים.
לפני הנפקת אסימון גישה לאפליקציה שלך, דרוש ביקור קיים ופעיל של Google כדי לבקש את הסכמת המשתמש ולתעד את התוצאה. יכול להיות שהמשתמש יצטרך להיכנס לחשבון Google אם עדיין אין סשן קיים.
כניסת משתמש
יכול להיות שהמשתמשים מחוברים לחשבון Google בכרטיסייה נפרדת בדפדפן, או שהם נכנסים דרך דפדפן או מערכת הפעלה. מומלץ להוסיף לאתר שלכם כניסה באמצעות חשבון Google כדי ליצור סשן פעיל בין חשבון Google לבין הדפדפן כשהמשתמש פותח את האפליקציה בפעם הראשונה. השימוש ביתרונות הבאים:
- מצמצם את מספר הפעמים שהמשתמש צריך להיכנס לחשבון, ובקשת אסימון גישה מתחילה את תהליך הכניסה לחשבון Google אם כבר יש סשן פעיל.
- מומלץ להשתמש בשדה פרטי הכניסה ל-
email
מזהה אסימון JWT בתור הערך של הפרמטרhint
באובייקטיםCodeClientConfig
אוTokenClientConfig
. האפשרות הזו מועילה במיוחד אם הפלטפורמה לא מנהלת מערכת של ניהול משתמשים. - אתם יכולים לחפש ולשייך חשבון Google לחשבון משתמש מקומי קיים בפלטפורמה כדי לצמצם את הכפילויות של החשבונות בפלטפורמה.
- כשנוצר חשבון מקומי חדש, אפשר להפריד בצורה ברורה בין תיבות הדו-שיח לתהליך ההרשמה, לבין תיבות הדו-שיח ותהליכי האימות של המשתמשים, וכך להפחית את מספר השלבים הנדרשים ולשפר את שיעור הנשירה מתהליך ההמרה.
אחרי הכניסה ולפני הנפקת אסימון גישה, המשתמשים חייבים לאשר את הבקשה עבור ההיקפים המבוקשים.
אסימון ובקשת הסכמה
לאחר ההסכמה, אסימון הגישה מוחזר ורשימת היקפים שאושרו או נדחו על ידי המשתמש.
הרשאות פרטניות מאפשרות למשתמשים לאשר או לדחות היקפים נפרדים. כשמבקשים גישה להיקפים מרובים, כל אחד מהם מקבל או נדחה בלי קשר להיקפים האחרים. בהתאם לבחירת המשתמש, האפליקציה מאפשרת באופן סלקטיבי תכונות ופונקציונליות שתלויות בהיקף ספציפי.
זרם הענקת גישה משתמע
החלפת הפניות של לקוחות ב-JavaScript לכניסה באמצעות חשבון Google בשירותי Google Identity:
אובייקטים:
gapi.auth2.AuthorizeResponse
עםTokenClient.TokenResponse
gapi.auth2.AuthResponse
עםTokenClient.TokenResponse
שיטות:
GoogleUser.hasGrantedScopes()
עםgoogle.accounts.oauth2.hasGrantedAllScopes()
GoogleUser.getGrantedScopes()
עםgoogle.accounts.oauth2.hasGrantedAllScopes()
הסרה הפניות לקוח של כניסה באמצעות חשבון Google:
שיטות:
GoogleUser.getAuthResponse()
עדכנו את אפליקציית האינטרנט שלכם ב-hasGrantedAllScopes()
וב-hasGrantedAnyScope()
בהתאם להרשאות המפורטות בדוגמה הזו.
תהליך קוד הרשאה
מומלץ לעדכן או להוסיף את נקודת הקצה של קוד ההרשאה לפלטפורמת הקצה העורפי באמצעות ההוראות לטיפול בקוד האימות.
מעדכנים את הפלטפורמה בהתאם לשלבים המפורטים במדריך בנושא שימוש בדגם הקוד, כדי לאמת את הבקשה ולקבל אסימון גישה ואסימון רענון.
מעדכנים את הפלטפורמה כדי להפעיל או להשבית באופן סלקטיבי תכונות ופונקציות בהתאם להיקפים הספציפיים שהמשתמש אישר, ופועלים לפי ההוראות להרשאה מצטברת ולבחינת היקפי הגישה שמוענקים על ידי המשתמש.
דוגמאות לזרימה משתמעת
הדרך הישנה
ספריית לקוח GAPI
דוגמה לספריית הלקוחות של Google API ל-JavaScript, שפועלת בדפדפן באמצעות תיבת דו-שיח קופצת שבה המשתמש מביע את הסכמתו.
המודול gapi.auth2
נטען באופן אוטומטי ונעשה בו שימוש על ידי gapi.client.init()
, ולכן הוא מוסתר.
<!DOCTYPE html>
<html>
<head>
<script src="https://apis.google.com/js/api.js"></script>
<script>
function start() {
gapi.client.init({
'apiKey': 'YOUR_API_KEY',
'clientId': 'YOUR_CLIENT_ID',
'scope': 'https://www.googleapis.com/auth/cloud-translation',
'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
}).then(function() {
// Execute an API request which is returned as a Promise.
// The method name language.translations.list comes from the API discovery.
return gapi.client.language.translations.list({
q: 'hello world',
source: 'en',
target: 'de',
});
}).then(function(response) {
console.log(response.result.data.translations[0].translatedText);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
};
// Load the JavaScript client library and invoke start afterwards.
gapi.load('client', start);
</script>
</head>
<body>
<div id="results"></div>
</body>
</html>
ספריית לקוח JS
פרוטוקול OAuth 2.0 לאפליקציות אינטרנט בצד הלקוח שפועל בדפדפן באמצעות תיבת דו-שיח קופצת לאישור משתמשים.
המודול gapi.auth2
נטען באופן ידני.
<!DOCTYPE html>
<html><head></head><body>
<script>
var GoogleAuth;
var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
function handleClientLoad() {
// Load the API's client and auth2 modules.
// Call the initClient function after the modules load.
gapi.load('client:auth2', initClient);
}
function initClient() {
// In practice, your app can retrieve one or more discovery documents.
var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';
// Initialize the gapi.client object, which app uses to make API requests.
// Get API key and client ID from API Console.
// 'scope' field specifies space-delimited list of access scopes.
gapi.client.init({
'apiKey': 'YOUR_API_KEY',
'clientId': 'YOUR_CLIENT_ID',
'discoveryDocs': [discoveryUrl],
'scope': SCOPE
}).then(function () {
GoogleAuth = gapi.auth2.getAuthInstance();
// Listen for sign-in state changes.
GoogleAuth.isSignedIn.listen(updateSigninStatus);
// Handle initial sign-in state. (Determine if user is already signed in.)
var user = GoogleAuth.currentUser.get();
setSigninStatus();
// Call handleAuthClick function when user clicks on
// "Sign In/Authorize" button.
$('#sign-in-or-out-button').click(function() {
handleAuthClick();
});
$('#revoke-access-button').click(function() {
revokeAccess();
});
});
}
function handleAuthClick() {
if (GoogleAuth.isSignedIn.get()) {
// User is authorized and has clicked "Sign out" button.
GoogleAuth.signOut();
} else {
// User is not signed in. Start Google auth flow.
GoogleAuth.signIn();
}
}
function revokeAccess() {
GoogleAuth.disconnect();
}
function setSigninStatus() {
var user = GoogleAuth.currentUser.get();
var isAuthorized = user.hasGrantedScopes(SCOPE);
if (isAuthorized) {
$('#sign-in-or-out-button').html('Sign out');
$('#revoke-access-button').css('display', 'inline-block');
$('#auth-status').html('You are currently signed in and have granted ' +
'access to this app.');
} else {
$('#sign-in-or-out-button').html('Sign In/Authorize');
$('#revoke-access-button').css('display', 'none');
$('#auth-status').html('You have not authorized this app or you are ' +
'signed out.');
}
}
function updateSigninStatus() {
setSigninStatus();
}
</script>
<button id="sign-in-or-out-button"
style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
style="display: none; margin-left: 25px">Revoke access</button>
<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body></html>
נקודות קצה ב-OAuth 2.0
פרוטוקול OAuth 2.0 לאפליקציות אינטרנט בצד הלקוח שפועל בדפדפן באמצעות הפניות אוטומטיות ל-Google לקבלת הסכמה מהמשתמשים.
בדוגמה הזו מוצגות קריאות ישירות לנקודות הקצה OAuth 2.0 של Google מהדפדפן של המשתמש, והוא לא משתמש במודול gapi.auth2
או בספריית JavaScript.
<!DOCTYPE html>
<html><head></head><body>
<script>
var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
var fragmentString = location.hash.substring(1);
// Parse query string to see if page request is coming from OAuth 2.0 server.
var params = {};
var regex = /([^&=]+)=([^&]*)/g, m;
while (m = regex.exec(fragmentString)) {
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
if (Object.keys(params).length > 0) {
localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
if (params['state'] && params['state'] == 'try_sample_request') {
trySampleRequest();
}
}
// If there's an access token, try an API request.
// Otherwise, start OAuth 2.0 flow.
function trySampleRequest() {
var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
if (params && params['access_token']) {
var xhr = new XMLHttpRequest();
xhr.open('GET',
'https://www.googleapis.com/drive/v3/about?fields=user&' +
'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.response);
} else if (xhr.readyState === 4 && xhr.status === 401) {
// Token invalid, so prompt for user permission.
oauth2SignIn();
}
};
xhr.send(null);
} else {
oauth2SignIn();
}
}
/*
* Create form to request access token from Google's OAuth 2.0 server.
*/
function oauth2SignIn() {
// Google's OAuth 2.0 endpoint for requesting an access token
var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';
// Create element to open OAuth 2.0 endpoint in new window.
var form = document.createElement('form');
form.setAttribute('method', 'GET'); // Send as a GET request.
form.setAttribute('action', oauth2Endpoint);
// Parameters to pass to OAuth 2.0 endpoint.
var params = {'client_id': YOUR_CLIENT_ID,
'redirect_uri': YOUR_REDIRECT_URI,
'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
'state': 'try_sample_request',
'include_granted_scopes': 'true',
'response_type': 'token'};
// Add form parameters as hidden input values.
for (var p in params) {
var input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', p);
input.setAttribute('value', params[p]);
form.appendChild(input);
}
// Add form to page and submit it to open the OAuth 2.0 endpoint.
document.body.appendChild(form);
form.submit();
}
</script>
<button onclick="trySampleRequest();">Try sample request</button>
</body></html>
הדרך החדשה
GIS בלבד
בדוגמה הזו מוצגת רק ספריית ה-JavaScript של Google Identity Service באמצעות מודל האסימון ותיבת הדו-שיח הקופצת בנושא הסכמת משתמשים. הוא נועד להמחיש את המספר המינימלי של השלבים הנדרשים להגדרת לקוח, לבקשת אסימון גישה ולביצוע קריאה ל-Google API.
<!DOCTYPE html>
<html>
<head>
<script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
</head>
<body>
<script>
var client;
var access_token;
function initClient() {
client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly \
https://www.googleapis.com/auth/contacts.readonly',
callback: (tokenResponse) => {
access_token = tokenResponse.access_token;
},
});
}
function getToken() {
client.requestAccessToken();
}
function revokeToken() {
google.accounts.oauth2.revoke(access_token, () => {console.log('access token revoked')});
}
function loadCalendar() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
xhr.send();
}
</script>
<h1>Google Identity Services Authorization Token model</h1>
<button onclick="getToken();">Get access token</button><br><br>
<button onclick="loadCalendar();">Load Calendar</button><br><br>
<button onclick="revokeToken();">Revoke token</button>
</body>
</html>
GAPI אסינכרוני/המתנה
בדוגמה הזו מוסבר איך להוסיף את הספרייה של Google Identity Service באמצעות מודל האסימון, להסיר את המודול gapi.auth2
ולקרוא ל-API באמצעות ספריית הלקוחות של Google API ל-JavaScript.
הבטחות, אסינכרוניות והמתנה משמשות לאכיפת סדר טעינה של ספריות, וזיהוי ניסיונות הרשאה חוזרים. קריאת API מתבצעת רק אחרי שאסימון גישה תקין זמין.
אנחנו מצפים מהמשתמשים ללחוץ על הלחצן 'הצגת היומן' כשאסימון הגישה חסר במהלך הטעינה הראשונה של הדף, או מאוחר יותר לאחר שפג התוקף של אסימון הגישה.
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1>GAPI with GIS async/await</h1>
<button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
<button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>
<script>
const gapiLoadPromise = new Promise((resolve, reject) => {
gapiLoadOkay = resolve;
gapiLoadFail = reject;
});
const gisLoadPromise = new Promise((resolve, reject) => {
gisLoadOkay = resolve;
gisLoadFail = reject;
});
var tokenClient;
(async () => {
document.getElementById("showEventsBtn").style.visibility="hidden";
document.getElementById("revokeBtn").style.visibility="hidden";
// First, load and initialize the gapi.client
await gapiLoadPromise;
await new Promise((resolve, reject) => {
// NOTE: the 'auth2' module is no longer loaded.
gapi.load('client', {callback: resolve, onerror: reject});
});
await gapi.client.init({
// NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
})
.then(function() { // Load the Calendar API discovery document.
gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
});
// Now load the GIS client
await gisLoadPromise;
await new Promise((resolve, reject) => {
try {
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
prompt: 'consent',
callback: '', // defined at request time in await/promise scope.
});
resolve();
} catch (err) {
reject(err);
}
});
document.getElementById("showEventsBtn").style.visibility="visible";
document.getElementById("revokeBtn").style.visibility="visible";
})();
async function getToken(err) {
if (err.result.error.code == 401 || (err.result.error.code == 403) &&
(err.result.error.status == "PERMISSION_DENIED")) {
// The access token is missing, invalid, or expired, prompt for user consent to obtain one.
await new Promise((resolve, reject) => {
try {
// Settle this promise in the response callback for requestAccessToken()
tokenClient.callback = (resp) => {
if (resp.error !== undefined) {
reject(resp);
}
// GIS has automatically updated gapi.client with the newly issued access token.
console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));
resolve(resp);
};
tokenClient.requestAccessToken();
} catch (err) {
console.log(err)
}
});
} else {
// Errors unrelated to authorization: server errors, exceeding quota, bad requests, and so on.
throw new Error(err);
}
}
function showEvents() {
// Try to fetch a list of Calendar events. If a valid access token is needed,
// prompt to obtain one and then retry the original request.
gapi.client.calendar.events.list({ 'calendarId': 'primary' })
.then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
.catch(err => getToken(err)) // for authorization errors obtain an access token
.then(retry => gapi.client.calendar.events.list({ 'calendarId': 'primary' }))
.then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
.catch(err => console.log(err)); // cancelled by user, timeout, etc.
}
function revokeToken() {
let cred = gapi.client.getToken();
if (cred !== null) {
google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
gapi.client.setToken('');
}
}
</script>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoadOkay()" onerror="gapiLoadFail(event)"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisLoadOkay()" onerror="gisLoadFail(event)"></script>
</body>
</html>
התקשרות חזרה של GAPI
בדוגמה הזו מוסבר איך להוסיף את הספרייה של Google Identity Service באמצעות מודל האסימון, להסיר את המודול gapi.auth2
ולקרוא ל-API באמצעות ספריית הלקוחות של Google API ל-JavaScript.
המשתנים משמשים לאכיפת סדר הטעינה של הספרייה. קריאות ל-GAPI מתבצעות מתוך הקריאה החוזרת (callback) אחרי שמתקבל אסימון גישה תקין.
אנחנו מצפים מהמשתמשים ללחוץ על הלחצן 'הצגת היומן' כשהדף נטען לראשונה, ופעם נוספת כשהם רוצים לרענן את הפרטים שלהם ביומן Google.
<!DOCTYPE html>
<html>
<head>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoad()"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisInit()"></script>
</head>
<body>
<h1>GAPI with GIS callbacks</h1>
<button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
<button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>
<script>
let tokenClient;
let gapiInited;
let gisInited;
document.getElementById("showEventsBtn").style.visibility="hidden";
document.getElementById("revokeBtn").style.visibility="hidden";
function checkBeforeStart() {
if (gapiInited && gisInited){
// Start only when both gapi and gis are initialized.
document.getElementById("showEventsBtn").style.visibility="visible";
document.getElementById("revokeBtn").style.visibility="visible";
}
}
function gapiInit() {
gapi.client.init({
// NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
})
.then(function() { // Load the Calendar API discovery document.
gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
gapiInited = true;
checkBeforeStart();
});
}
function gapiLoad() {
gapi.load('client', gapiInit)
}
function gisInit() {
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: '', // defined at request time
});
gisInited = true;
checkBeforeStart();
}
function showEvents() {
tokenClient.callback = (resp) => {
if (resp.error !== undefined) {
throw(resp);
}
// GIS has automatically updated gapi.client with the newly issued access token.
console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));
gapi.client.calendar.events.list({ 'calendarId': 'primary' })
.then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
.catch(err => console.log(err));
document.getElementById("showEventsBtn").innerText = "Refresh Calendar";
}
// Conditionally ask users to select the Google Account they'd like to use,
// and explicitly obtain their consent to fetch their Calendar.
// NOTE: To request an access token a user gesture is necessary.
if (gapi.client.getToken() === null) {
// Prompt the user to select a Google Account and asked for consent to share their data
// when establishing a new session.
tokenClient.requestAccessToken({prompt: 'consent'});
} else {
// Skip display of account chooser and consent dialog for an existing session.
tokenClient.requestAccessToken({prompt: ''});
}
}
function revokeToken() {
let cred = gapi.client.getToken();
if (cred !== null) {
google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
gapi.client.setToken('');
document.getElementById("showEventsBtn").innerText = "Show Calendar";
}
}
</script>
</body>
</html>
דוגמאות לזרימת קוד הרשאה
חוויית המשתמש של הספרייה של Google Identity Service יכולה להשתמש בהפניה אוטומטית של כתובת URL כדי להחזיר קוד הרשאה ישירות לנקודת הקצה של האסימון העורפי, או ב-handler לקריאה חוזרת (callback) של JavaScript בדפדפן של המשתמש שמעביר את התגובה לפלטפורמה. בכל אחד מהמקרים, פלטפורמת הקצה העורפי תשלים את תהליך OAuth 2.0 כדי לקבל אסימון רענון וגישה חוקיים.
הדרך הישנה
אפליקציות אינטרנט בצד השרת
כניסה באמצעות חשבון Google לאפליקציות בצד השרת שפועלת בפלטפורמת קצה עורפי באמצעות הפניה אוטומטית ל-Google לקבלת הסכמה מהמשתמשים.
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
<script>
function start() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: 'YOUR_CLIENT_ID',
api_key: 'YOUR_API_KEY',
discovery_docs: ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
// Scopes to request in addition to 'profile' and 'email'
scope: 'https://www.googleapis.com/auth/cloud-translation',
});
});
}
function signInCallback(authResult) {
if (authResult['code']) {
console.log("sending AJAX request");
// Send authorization code obtained from Google to backend platform
$.ajax({
type: 'POST',
url: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URL',
// Always include an X-Requested-With header to protect against CSRF attacks.
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
contentType: 'application/octet-stream; charset=utf-8',
success: function(result) {
console.log(result);
},
processData: false,
data: authResult['code']
});
} else {
console.log('error: failed to obtain authorization code')
}
}
</script>
</head>
<body>
<button id="signinButton">Sign In With Google</button>
<script>
$('#signinButton').click(function() {
// Obtain an authorization code from Google
auth2.grantOfflineAccess().then(signInCallback);
});
</script>
</body>
</html>
HTTP/REST באמצעות הפניה אוטומטית
שימוש ב-OAuth 2.0 לאפליקציות של שרת אינטרנט כדי לשלוח קוד הרשאה מהדפדפן של המשתמש לפלטפורמת הקצה העורפי. הסכמת המשתמש מטופלת על ידי הפניה אוטומטית של דפדפן המשתמש ל-Google.
/\*
\* Create form to request access token from Google's OAuth 2.0 server.
\*/
function oauthSignIn() {
// Google's OAuth 2.0 endpoint for requesting an access token
var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';
// Create <form> element to submit parameters to OAuth 2.0 endpoint.
var form = document.createElement('form');
form.setAttribute('method', 'GET'); // Send as a GET request.
form.setAttribute('action', oauth2Endpoint);
// Parameters to pass to OAuth 2.0 endpoint.
var params = {'client\_id': 'YOUR_CLIENT_ID',
'redirect\_uri': 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URL',
'response\_type': 'token',
'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
'include\_granted\_scopes': 'true',
'state': 'pass-through value'};
// Add form parameters as hidden input values.
for (var p in params) {
var input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', p);
input.setAttribute('value', params[p]);
form.appendChild(input);
}
// Add form to page and submit it to open the OAuth 2.0 endpoint.
document.body.appendChild(form);
form.submit();
}
הדרך החדשה
חוויית משתמש קופצת של GIS
בדוגמה הזו מוצגת רק ספריית JavaScript של שירות Google Identityבאמצעות המודל של קוד ההרשאה – תיבת דו-שיח קופצת לאישור משתמשים ולמטפלים חזרה (callback) לקבלת קוד ההרשאה מ-Google. הוא נועד להדגים את המספר המינימלי של השלבים הנדרשים להגדרת לקוח, לקבלת הסכמה ולשליחת קוד הרשאה לפלטפורמת הקצה העורפי.
<!DOCTYPE html>
<html>
<head>
<script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
</head>
<body>
<script>
var client;
function initClient() {
client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
ux_mode: 'popup',
callback: (response) => {
var code_receiver_uri = 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI',
// Send auth code to your backend platform
const xhr = new XMLHttpRequest();
xhr.open('POST', code_receiver_uri, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function() {
console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('code=' + response.code);
// After receipt, the code is exchanged for an access token and
// refresh token, and the platform then updates this web app
// running in user's browser with the requested calendar info.
},
});
}
function getAuthCode() {
// Request authorization code and obtain user consent
client.requestCode();
}
</script>
<button onclick="getAuthCode();">Load Your Calendar</button>
</body>
</html>
חוויית משתמש עם הפניה אוטומטית ל-GIS
מודל של קוד הרשאה תומך במצבים של חלונות קופצים והפנייה אוטומטית של חוויית המשתמש, כדי לשלוח קוד הרשאה לכל משתמש לנקודת הקצה שמתארחת בפלטפורמה. מצב חוויית המשתמש להפניה האוטומטית מוצג כאן:
<!DOCTYPE html>
<html>
<head>
<script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
</head>
<body>
<script>
var client;
function initClient() {
client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly \
https://www.googleapis.com/auth/photoslibrary.readonly',
ux_mode: 'redirect',
redirect_uri: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI'
});
}
// Request an access token
function getAuthCode() {
// Request authorization code and obtain user consent
client.requestCode();
}
</script>
<button onclick="getAuthCode();">Load Your Calendar</button>
</body>
</html>
ספריות JavaScript
שירותי Google Identity הם ספריית JavaScript אחת המשמשת לאימות ולהרשאה של משתמשים, המאחדת ומחליפה את התכונות והפונקציות שנמצאות במספר ספריות ומודולים:
פעולות לביצוע בזמן המעבר לשירותי זיהוי:
ספריית JS קיימת | ספריית JS חדשה | הערות |
---|---|---|
apis.google.com/js/api.js |
accounts.google.com/gsi/client |
מוסיפים ספרייה חדשה ופועלים לפי התהליך המשתמע. |
apis.google.com/js/client.js |
accounts.google.com/gsi/client |
הוספת ספרייה חדשה ותהליך קוד ההרשאה. |
הסבר קצר על ספרייה
השוואת אובייקטים ושיטות בין הספרייה הקודם לקוח JavaScript בכניסה לחשבון לבין הספרייה חדש שירותי Google Identity והערות עם מידע ופעולה נוספים שצריך לבצע במהלך ההעברה.
ישן | חדש | הערות |
---|---|---|
אובייקט GoogleAuth והשיטות המשויכות אליו: | ||
GoogleAuth.attachClickHandler() | הסרה | |
GoogleAuth.currentUser.get() | הסרה | |
GoogleAuth.currentUser.listen() | הסרה | |
GoogleAuth.disconnect() | google.accounts.oauth2.revoke | מחליפים את הישן לחדש. ביטול עשוי גם להתרחש בכתובת https://myaccount.google.com/permissions |
GoogleAuth.grantOfflineAccess() | יש להסיר אותם בהתאם לתהליך של קוד ההרשאה. | |
GoogleAuth.isSignatureIn.get() | הסרה | |
GoogleAuth.isSignedIn.listen() | הסרה | |
GoogleAuth.signIn() | הסרה | |
GoogleAuth.signOut() | הסרה | |
GoogleAuth.then() | הסרה | |
אובייקט GoogleUser והשיטות המשויכות אליו: | ||
GoogleUser.disconnect() | google.accounts.id.revoke | מחליפים את הישן לחדש. ביטול עשוי גם להתרחש בכתובת https://myaccount.google.com/permissions |
GoogleUser.getAuthResponse() | requestCode() או requestAccessToken() | מחליפים את הישן לחדש |
GoogleUser.getBasicProfile() | הסרה. השתמש במקום זאת באסימון מזהה, במאמר מעבר מכניסה באמצעות חשבון Google. | |
GoogleUser.getGrantedScopes() | hasgranted AnyScope() | מחליפים את הישן לחדש |
GoogleUser.getHostedDomain() | הסרה | |
GoogleUser.getId() | הסרה | |
GoogleUser.grantOfflineAccess() | יש להסיר אותם בהתאם לתהליך של קוד ההרשאה. | |
GoogleUser.grant() | הסרה | |
GoogleUser.hasgrantedScopes() | hasgranted AnyScope() | מחליפים את הישן לחדש |
GoogleUser.isSignedIn() | הסרה | |
GoogleUser.reloadAuthResponse() | requestAccessToken() | הסרת הגרסה הישנה, הפעלת 'שיחה חדשה' והחלפת אסימון גישה שתוקפו פג או שתוקפו בוטל. |
אובייקט gapi.auth2 והשיטות המשויכות אליו: | ||
אובייקט gapi.auth2.AuthorizeConfig | TokenClientConfig או CodeClientConfig | מחליפים את הישן לחדש |
gapi.auth2.AuthorizeResponse אובייקט | הסרה | |
gapi.auth2.AuthResponse אובייקט | הסרה | |
gapi.auth2.authorize() | requestCode() או requestAccessToken() | מחליפים את הישן לחדש |
gapi.auth2.ClientConfig() | TokenClientConfig או CodeClientConfig | מחליפים את הישן לחדש |
gapi.auth2.getAuthInstance() | הסרה | |
gapi.auth2.init() | initTokenClient() או initCodeClient() | מחליפים את הישן לחדש |
אובייקט gapi.auth2.OfflineAccessOption | הסרה | |
אובייקט gapi.auth2.SignInOption | הסרה | |
אובייקט gapi.signin2 והשיטות המשויכות אליו: | ||
gapi.signin2.render() | הסרה. טעינת ה-DOM DOM של g_id_signin או קריאת JS ל- google.accounts.id.renderButton מפעילה את כניסת המשתמש לחשבון Google. |
דוגמאות לפרטי כניסה
פרטי כניסה קיימים
ספריית הפלטפורמות של הכניסה באמצעות חשבון Google, ספריית הלקוחות של Google API עבור JavaScript, או קריאות ישירות לנקודות הקצה של Google Auth 2.0 יחזירו אסימון גישה מסוג OAuth 2.0 וגם אסימון OpenID Connect ID באסימון יחיד.
דוגמה לתגובה שמכילה גם את access_token
וגם את id_token
:
{
"token_type": "Bearer",
"access_token": "ya29.A0ARrdaM-SmArZaCIh68qXsZSzyeU-8mxhQERHrP2EXtxpUuZ-3oW8IW7a6D2J6lRnZrRj8S6-ZcIl5XVEqnqxq5fuMeDDH_6MZgQ5dgP7moY-yTiKR5kdPm-LkuPM-mOtUsylWPd1wpRmvw_AGOZ1UUCa6UD5Hg",
"scope": "https://www.googleapis.com/auth/calendar.readonly",
"login_hint": "AJDLj6I2d1RH77cgpe__DdEree1zxHjZJr4Q7yOisoumTZUmo5W2ZmVFHyAomUYzLkrluG-hqt4RnNxrPhArd5y6p8kzO0t8xIfMAe6yhztt6v2E-_Bb4Ec3GLFKikHSXNh5bI-gPrsI",
"expires_in": 3599,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjkzNDFhYmM0MDkyYjZmYzAzOGU0MDNjOTEwMjJkZDNlNDQ1MzliNTYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE3NzI2NDMxNjUxOTQzNjk4NjAwIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6IkJBSW55TjN2MS1ZejNLQnJUMVo0ckEiLCJuYW1lIjoiQnJpYW4gRGF1Z2hlcnR5IiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hLS9BT2gxNEdnenAyTXNGRGZvbVdMX3VDemRYUWNzeVM3ZGtxTE5ybk90S0QzVXNRPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkJyaWFuIiwiZmFtaWx5X25hbWUiOiJEYXVnaGVydHkiLCJsb2NhbGUiOiJlbiIsImlhdCI6MTYzODk5MTYzOCwiZXhwIjoxNjM4OTk1MjM4LCJqdGkiOiI5YmRkZjE1YWFiNzE2ZDhjYmJmNDYwMmM1YWM3YzViN2VhMDQ5OTA5In0.K3EA-3Adw5HA7O8nJVCsX1HmGWxWzYk3P7ViVBb4H4BoT2-HIgxKlx1mi6jSxIUJGEekjw9MC-nL1B9Asgv1vXTMgoGaNna0UoEHYitySI23E5jaMkExkTSLtxI-ih2tJrA2ggfA9Ekj-JFiMc6MuJnwcfBTlsYWRcZOYVw3QpdTZ_VYfhUu-yERAElZCjaAyEXLtVQegRe-ymScra3r9S92TA33ylMb3WDTlfmDpWL0CDdDzby2asXYpl6GQ7SdSj64s49Yw6mdGELZn5WoJqG7Zr2KwIGXJuSxEo-wGbzxNK-mKAiABcFpYP4KHPEUgYyz3n9Vqn2Tfrgp-g65BQ",
"session_state": {
"extraQueryParams": {
"authuser": "0"
}
},
"first_issued_at": 1638991637982,
"expires_at": 1638995236982,
"idpId": "google"
}
פרטי הכניסה לשירותי Google Identity
אפשר לחזור אל הספרייה של שירותי Google Identity:
- אסימון גישה שישמש להרשאה:
{
"access_token": "ya29.A0ARrdaM_LWSO-uckLj7IJVNSfnUityT0Xj-UCCrGxFQdxmLiWuAosnAKMVQ2Z0LLqeZdeJii3TgULp6hR_PJxnInBOl8UoUwWoqsrGQ7-swxgy97E8_hnzfhrOWyQBmH6zs0_sUCzwzhEr_FAVqf92sZZHphr0g",
"token_type": "Bearer",
"expires_in": 3599,
"scope": "https://www.googleapis.com/auth/calendar.readonly"
}
- או אסימון מזהה בזמן האימות:
{
"clientId": "538344653255-758c5h5isc45vgk27d8h8deabovpg6to.apps.googleusercontent.com",
"credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxODkyZWI0OWQ3ZWY5YWRmOGIyZTE0YzA1Y2EwZDAzMjcxNGEyMzciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2MzkxNTcyNjQsImF1ZCI6IjUzODM0NDY1MzI1NS03NThjNWg1aXNjNDV2Z2syN2Q4aDhkZWFib3ZwZzZ0by5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjExNzcyNjQzMTY1MTk0MzY5ODYwMCIsIm5vbmNlIjoiZm9vYmFyIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwibmFtZSI6IkJyaWFuIERhdWdoZXJ0eSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQU9oMTRHZ3pwMk1zRkRmb21XTF91Q3pkWFFjc3lTN2RrcUxOcm5PdEtEM1VzUT1zOTYtYyIsImdpdmVuX25hbWUiOiJCcmlhbiIsImZhbWlseV9uYW1lIjoiRGF1Z2hlcnR5IiwiaWF0IjoxNjM5MTU3NTY0LCJleHAiOjE2MzkxNjExNjQsImp0aSI6IjRiOTVkYjAyZjU4NDczMmUxZGJkOTY2NWJiMWYzY2VhYzgyMmI0NjUifQ.Cr-AgMsLFeLurnqyGpw0hSomjOCU4S3cU669Hyi4VsbqnAV11zc_z73o6ahe9Nqc26kPVCNRGSqYrDZPfRyTnV6g1PIgc4Zvl-JBuy6O9HhClAK1HhMwh1FpgeYwXqrng1tifmuotuLQnZAiQJM73Gl-J_6s86Buo_1AIx5YAKCucYDUYYdXBIHLxrbALsA5W6pZCqqkMbqpTWteix-G5Q5T8LNsfqIu_uMBUGceqZWFJALhS9ieaDqoxhIqpx_89QAr1YlGu_UO6R6FYl0wDT-nzjyeF5tonSs3FHN0iNIiR3AMOHZu7KUwZaUdHg4eYkU-sQ01QNY_11keHROCRQ",
"select_by": "user"
}
תגובת אסימון לא חוקית
דוגמה לתגובה מ-Google כשמנסים להגיש בקשת API באמצעות אסימון גישה שתוקפו פג, בוטל או שאינו חוקי:
כותרות תגובה ב-HTTP
www-authenticate: Bearer realm="https://accounts.google.com/", error="invalid_token"
גוף התגובה
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"errors": [
{
"message": "Invalid Credentials",
"domain": "global",
"reason": "authError",
"location": "Authorization",
"locationType": "header"
}
],
"status": "UNAUTHENTICATED"
}
}