שימוש ב-OAuth 2.0 ל'שרתים לשרת'

אם יש למידע נוסף, ראו סקירה כללית על אימות במסמכי התיעוד של Google Cloud Platform.

מערכת Google OAuth 2.0 תומכת באינטראקציות בין שרתים, כמו אינטראקציות בין אפליקציית אינטרנט לבין שירות של Google. בתרחיש הזה צריך חשבון שירות, שהוא חשבון ששייך לאפליקציה ולא משתמש קצה יחיד. האפליקציה שלך מתקשרת ל-Google APIs בשם חשבון השירות, כך שהמשתמשים לא מעורבים באופן ישיר. תרחיש זה נקרא לפעמים "two-legg OAuth OAuth," או "2LO." (המונח הקשור " Three-legg OAuth OAuth" מתייחס לתרחישים שבהם האפליקציה שלך מפעילה את ממשקי ה-API של Google בשם משתמשי קצה, ושבהם נדרשת הסכמת משתמשים לפעמים.)

בדרך כלל, אפליקציה משתמשת בחשבון שירות כאשר האפליקציה משתמשת ב-Google APIs כדי לעבוד עם נתונים משלה, במקום עם נתוני המשתמש. לדוגמה, אפליקציה שמשתמשת ב-Google Cloud Datastore לאחסון נתונים מתמשך תשתמש בחשבון שירות כדי לאמת את הקריאה שלה ל-Google Cloud Datastore API.

מנהלי דומיינים ב-Google Workspace יכולים גם להעניק לחשבון המשתמשים שירות בדומיין כולו הרשאה לגשת לנתוני המשתמשים בשם המשתמשים.

מסמך זה מתאר כיצד אפליקציה יכולה להשלים את זרימת OAuth 2.0 משרת לשרת באמצעות ספריית לקוח של Google APIs (מומלץ) או HTTP.

סקירה כללית

כדי לתמוך באינטראקציות בין שרתים, יש ליצור תחילה חשבון שירות לפרויקט שלך ב . כדי לקבל גישה לנתוני המשתמשים של משתמשים בחשבון Google Workspace, עליך להעניק לחשבון השירות גישה ברמת הדומיין לחשבון השירות.

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

לבסוף, האפליקציה שלכם יכולה להשתמש באסימון הגישה כדי לקרוא ל-Google APIs.

יצירת חשבון שירות

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

אם האפליקציה שלך פועלת ב-Google App Engine, חשבון השירות מוגדר באופן אוטומטי כשיוצרים את הפרויקט.

אם האפליקציה שלך פועלת ב-Google Compute Engine, חשבון השירות מוגדר גם באופן אוטומטי כשיוצרים את הפרויקט. עם זאת, כשיוצרים את המופע של Google Compute Engine, צריך לציין את ההיקפים שאליהם האפליקציה צריכה גישה. למידע נוסף, אפשר לקרוא מידע נוסף במאמר הכנת מכונה לשימוש בחשבונות שירות.

אם האפליקציה שלך לא פועלת ב-Google App Engine או ב-Google Compute Engine, עליך לקבל את פרטי הכניסה האלה ב . כדי ליצור פרטי כניסה לחשבון שירות, או כדי להציג את פרטי הכניסה הציבוריים, שכבר יצרת, עליך לבצע את הפעולות הבאות:

ראשית, צור חשבון שירות:

  1. פתח את ה- Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. לחץ על צור חשבון שירות .
  4. תחת פרטי חשבון שירות , הקלד שם, מזהה ותיאור עבור חשבון השירות ולאחר מכן לחץ על צור והמשך .
  5. אופציונלי: תחת הענק גישה לחשבון שירות זה לפרויקט , בחר את תפקידי IAM להעניק לחשבון השירות.
  6. לחץ על המשך .
  7. אופציונלי: תחת הענק למשתמשים גישה לחשבון שירות זה , הוסף את המשתמשים או הקבוצות המורשים להשתמש ולנהל את חשבון השירות.
  8. לחץ על סיום .

לאחר מכן, צור מפתח חשבון שירות:

  1. לחץ על כתובת הדוא"ל של חשבון השירות שיצרת.
  2. לחץ על הכרטיסייה מפתחות .
  3. ברשימה הנפתחת הוסף מפתח , בחר צור מפתח חדש .
  4. לחץ על צור .

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

אפשר לחזור אל API Console בכל שלב כדי להציג את כתובת האימייל, טביעות האצבע של המפתח הציבורי ומידע נוסף, או כדי ליצור זוגות נוספים של מפתח ציבורי/פרטי. לפרטים נוספים על פרטי הכניסה לחשבון השירות ב- API Console, אפשר לעיין בחשבונות שירות בקובץ העזרה API Console.

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

האצלת סמכות ברמת הדומיין לחשבון השירות

אם יש לך חשבון Google Workspace, האדמין של הארגון יכול לאפשר לאפליקציה לגשת לנתוני המשתמשים בשם משתמשים בדומיין Google Workspace. לדוגמה, אפליקציה שמשתמשת ב-API של יומן Google כדי להוסיף אירועים ליומנים של כל המשתמשים בדומיין Google Workspace, תשתמש בחשבון שירות כדי לגשת ל-API של יומן Google בשם משתמשים. מתן הרשאה לחשבון שירות לגשת לנתונים בשם משתמשים בדומיין נקרא לפעמים "הענקת סמכות ברמת הדומיין" לחשבון שירות.

כדי להעניק סמכות ברמת הדומיין לחשבון שירות, סופר-אדמין בדומיין Google Workspace צריך להשלים את השלבים הבאים:

  1. מתוך הדומיין של Google Workspace מסוף Admin, עוברים אל התפריט הראשי > אבטחה > גישה לנתונים ול> בקרות API.
  2. בחלונית הענקת גישה ברמת הדומיין, בוחרים באפשרות ניהול של הענקת גישה ברמת הדומיין.
  3. לוחצים על הוספת חדש.
  4. בשדה Client ID, יש להזין את Client ID של חשבון השירות. ניתן למצוא את מספר הלקוח בחשבון השירות ב Service accounts page.
  5. בשדה היקפי הרשאות OAuth (מופרדים בפסיקים), מזינים את רשימת ההיקפים שבהם האפליקציה שלך צריכה לקבל גישה. לדוגמה, אם לאפליקציה דרושה גישה מלאה לכל הדומיין ל-Google Drive API ול-Google Calendar API, מזינים: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
  6. לוחצים על Authorize.

כעת לאפליקציה שלך יש הרשאה לבצע קריאות ל-API כמשתמשים בדומיין שלך (כדי "התחזות{/3}. כשמתכוננים לבצע קריאות ל-API מורשות, צריך לציין את המשתמש שיוכלו להתחזות.

בהכנה לבצע קריאה מורשית ל-API

Java

אחרי שמוצאים את כתובת האימייל והמפתח הפרטי של הלקוח מ- API Console, יש להשתמש בספריית הלקוחות של Google APIs ל-Java כדי ליצור אובייקט GoogleCredential מפרטי הכניסה של חשבון השירות ובהיקפי ההרשאות שהאפליקציה צריכה לגשת אליהם. למשל:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

אם אתם מפתחים אפליקציה ב-Google Cloud Platform, תוכלו להשתמש בפרטי הכניסה שמוגדרים כברירת מחדל באפליקציה במקום זאת, וכך לפשט את התהליך.

האצלת סמכות ברמת הדומיין

אם הענקת גישה לחשבון ברמת הדומיין לחשבון וברצונך להתחזות לחשבון משתמש, יש לציין את כתובת האימייל של חשבון המשתמש בשיטה createDelegated של האובייקט GoogleCredential. לדוגמה:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("user@example.com");

אפשר להשתמש באובייקט GoogleCredential כדי לקרוא ל-Google APIs באפליקציה.

Python

אחרי שמקבלים את כתובת האימייל והמפתח הפרטי של הלקוח מ- API Console, צריך להשתמש בספריית הלקוחות של Google APIs ל-Python כדי לבצע את השלבים הבאים:

  1. יצירת אובייקט Credentials מפרטי הכניסה של חשבון השירות ומהיקפי ההרשאות שלהם האפליקציה שלך צריכה גישה. למשל:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    אם אתם מפתחים אפליקציה ב-Google Cloud Platform, תוכלו להשתמש בפרטי הכניסה שמוגדרים כברירת מחדל באפליקציה במקום זאת, וכך לפשט את התהליך.

  2. האצלת סמכות ברמת הדומיין

    אם הענקת גישה לחשבון ברמת הדומיין לחשבון וברצונך להתחזות לחשבון משתמש, צריך להשתמש בשיטה with_subject של אובייקט ServiceAccountCredentials קיים. למשל:

    delegated_credentials = credentials.with_subject('user@example.org')

ניתן להשתמש באובייקט פרטי הכניסה כדי להפעיל את Google APIs באפליקציה.

HTTP/REST

אחרי שמקבלים את מספר הלקוח והמפתח הפרטי מ- API Console, צריך להשלים את השלבים הבאים באפליקציה שלך:

  1. יוצרים אסימון אינטרנט מסוג JSON (JWT, הגייה, "jot") שכולל כותרת, קבוצת תלונות וחתימה.
  2. בקשת אסימון גישה משרת ההרשאות של Google OAuth 2.0.
  3. יש לטפל בתגובת ה-JSON ששרת ההרשאות מחזיר.

הקטעים הבאים מתארים איך לבצע את השלבים האלה.

אם התשובה כוללת אסימון גישה, אפשר להשתמש באסימון הגישה כדי להתקשר ל-Google API. (אם התגובה לא כוללת אסימון גישה, ייתכן שה-JWT ובקשת האסימון לא נוצרו כראוי, או שלחשבון השירות אין הרשאה לגשת להיקפים המבוקשים).

כשאסימון הגישה יפוג, האפליקציה יוצרת קוד JWT נוסף, חותמת ומבקשת אסימון גישה אחר.

אפליקציית השרת שלך משתמשת ב-JWT כדי לבקש אסימון משרת ההרשאות של Google, ואז משתמשת באסימון כדי לקרוא לנקודת קצה (endpoint) של Google API. אין
                  משתמש קצה מעורב.

שאר הסעיף הזה מפרט את הפרטים הספציפיים ליצירת JWT, חתימה על JWT, יצירת בקשת אסימון גישה וטיפול בתגובה.

יצירת JWT

JWT מורכב משלושה חלקים: כותרת, קבוצת תלונות וחתימה. הכותרת וקבוצת התלונות הן אובייקטים בפורמט JSON. אובייקטים אלה של JSON טוריים ל-UTF-8 בייט, ואז מקודדים באמצעות קידוד Base64url. הקידוד הזה מספק גמישות בשינויי הקידוד עקב פעולות קידוד חוזרות. הכותרת, מערך התלונות והחתימה משורשרים יחד עם תו נקודה (.).

JWT מורכב באופן הבא:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

מחרוזת הבסיס של החתימה היא:

{Base64url encoded header}.{Base64url encoded claim set}
יצירת כותרת JWT

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

חשבונות שירות מסתמכים על אלגוריתם RSA SHA-256 ועל פורמט אסימון JWT. כתוצאה מכך, ייצוג ה-JSON של הכותרת הוא:

{"alg":"RS256","typ":"JWT"}

הייצוג של Base64url הוא:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
יצירת קבוצת התלונות ל-JWT

קבוצת התלונות של JWT מכילה מידע על ה-JWT, כולל ההרשאות שהתבקשו (היקף), יעד האסימון, המנפיק, הזמן שבו האסימון הונפק ומשך החיים של האסימון. רוב השדות הם שדות חובה. בדומה לכותרת JWT, קבוצת התלונות של JWT היא אובייקט JSON ומשמשת לחישוב החתימה.

תלונות נדרשות

התלונות הנדרשות בקבוצת התלונות של JWT מוצגות למטה. הם עשויים להופיע בכל סדר בקבוצת התלונות.

שם תיאור
iss כתובת האימייל של חשבון השירות.
scope רשימה מופרדת ברווחים של ההרשאות שהאפליקציה מבקשת.
aud מתאר של היעד של הטענה. כששולחים אסימון גישה, הערך הזה הוא תמיד https://oauth2.googleapis.com/token.
exp מועד התפוגה של הקביעה, שהוגדר בשניות מאז 00:00:00 UTC, 1 בינואר 1970. הערך הזה יכול להיות שעה אחת לכל היותר לאחר הזמן שהונפק.
iat המועד שבו נשלחה ההצהרה, בשניות, 00:00:00 UTC, 1 בינואר 1970.

בהמשך מוצגים תצוגת ה-JSON של השדות הנדרשים בקבוצת תלונות של JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
תלונות נוספות

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

כדי לקבל אסימון גישה שמעניק לאפליקציה גישה מואצלת למשאב, צריך לכלול את כתובת האימייל של המשתמש בתביעת JWT שהוגדרה כערך של sub.

שם תיאור
sub כתובת האימייל של המשתמש שעבורו האפליקציה מבקשת גישה.

אם לאפליקציה אין הרשאה להתחזות למשתמש, התגובה לבקשה של אסימון גישה שכוללת את השדה sub תהיה שגיאה.

דוגמה לקבוצת תלונות של JWT שכוללת את השדה sub:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
קידוד קבוצת התלונות של JWT

כמו הכותרת של JWT, יש לסדר את קבוצת התלונות של WWT לקידוד ב-UTF-8 ובקידוד Base64url. הנה דוגמה לייצוג JSON של תלונה של JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
חישוב החתימה מתבצע

חתימה באינטרנט בפורמט JSON (JWS) היא המפרט של מפרט המכניקה של יצירת החתימה עבור JWT. הקלט לחתימה הוא מערך הבייט של התוכן הבא:

{Base64url encoded header}.{Base64url encoded claim set}

יש להשתמש באלגוריתם החתימה בכותרת JWT בעת חישוב החתימה. אלגוריתם החתימה היחיד שנתמך על ידי שרת ההרשאות של Google OAuth 2.0 הוא RSA באמצעות אלגוריתם הגיבוב SHA-256. נתון זה מוצג בתור RS256 בשדה alg בכותרת JWT.

חותמים את ייצוג UTF-8 של הקלט באמצעות SHA256withRSA (שנקרא גם RSASSA-PKCS1-V1_5-SIGN עם פונקציית הגיבוב SHA-256) עם המפתח הפרטי שמתקבל מ- Google API Console. הפלט יהיה מערך בייט.

החתימה חייבת להיות בקידוד Base64url. הכותרת, קבוצת התלונות והחתימה משורשרים יחד עם תו נקודה (.). התוצאה היא ה-JWT. הקוד אמור להיות הבא (הוספה של מעברי שורה כדי להבהיר):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

דוגמה ל-JWT לפני קידוד Base64url:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

הנה דוגמה ל-JWT חתום ומוכן להעברה:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

שליחת הבקשה לאסימון הגישה

לאחר יצירת JWT חתום, אפליקציה יכולה להשתמש בו כדי לבקש אסימון גישה. בקשת אסימון הגישה הזו היא בקשת POST HTTPS, והגוף מקודד בכתובת ה-URL. כתובת ה-URL מוצגת למטה:

https://oauth2.googleapis.com/token

חובה לבקש את הפרמטרים הבאים ב-HTTPS POST:

שם תיאור
grant_type צריך להשתמש במחרוזת הבאה, בקידוד כתובת URL לפי הצורך: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion JWT, כולל חתימה.

לפניכם קובץ נתונים גולמי של בקשת HTTPS בחיבור POST שנעשה בו שימוש בבקשת אסימון גישה:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

בהמשך לאותה בקשה, באמצעות curl:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

הטיפול בתגובה

אם בקשת ה-JWT ובקשת הגישה הוזנו כראוי ולחשבון השירות יש הרשאה לבצע את הפעולה, תגובת ה-JSON משרת ההרשאות תכלול אסימון גישה. לפניכם תשובה לדוגמה:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

ניתן לעשות שימוש חוזר באסימוני גישה במהלך חלון הזמן שצוין בערך expires_in.

קריאה ל-Google APIs

Java

כדי להתקשר ל-Google APIs באמצעות האובייקט GoogleCredential, יש לבצע את השלבים הבאים:

  1. יצירת אובייקט שירות עבור ה-API שאליו ברצונך להתקשר באמצעות האובייקט GoogleCredential. למשל:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. שולחים בקשות לשירות ה-API באמצעות הממשק שסופק על ידי האובייקט של השירות. לדוגמה, כדי לפרט את המופעים של מסדי נתונים ב-Cloud SQL בפרויקט המרגש-example-123, :
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

אפשר להשתמש באובייקט Credentials המורשה כדי להתקשר ל-Google APIs על ידי ביצוע השלבים הבאים:

  1. יוצרים אובייקט שירות עבור ה-API שאליו רוצים להפעיל. יש לבנות אובייקט שירות על ידי קריאה לפונקציה build בשם ובגרסה של ה-API, ובאובייקט Credentials המורשה. לדוגמה, כדי לבצע קריאה לגרסה 1 בטא של Cloud SQL Administration API:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. שולחים בקשות לשירות ה-API באמצעות הממשק שסופק על ידי האובייקט של השירות. לדוגמה, כדי לפרט את המופעים של מסדי נתונים ב-Cloud SQL בפרויקט המרגש-example-123, :
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

לאחר שהאפליקציה שלך תקבל אסימון גישה, ניתן להשתמש באסימון כדי לבצע קריאות ל-API של Google בשם חשבון שירות נתון או חשבון משתמש מסוים, אם היקפי הגישה הנדרשים על ידי ה-API אושרו. כדי לעשות זאת, יש לכלול את אסימון הגישה בבקשה ל-API. לשם כך, צריך לכלול פרמטר access_token של שאילתה או ערך Authorization של כותרת HTTP Bearer. אם אפשר, מומלץ שהכותרת תהיה מסוג HTTP, כי מחרוזות שאילתה בדרך כלל גלויות ביומני השרת. לרוב, אפשר להשתמש בספריית לקוחות כדי להגדיר את השיחות ל-Google APIs (לדוגמה, כשמתקשרים ל-Drive Files API).

אפשר לנסות את כל ממשקי ה-API של Google ולהציג את ההיקפים שלהם במגרש המשחקים OAuth 2.0.

דוגמאות ל-HTTP GET

קריאה לנקודת הקצה drive.files (ב-Drive Files API) באמצעות כותרת ה-HTTP Authorization: Bearer עשויה להיראות כך: הערה: עליכם לציין את אסימון הגישה שלכם:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

זו קריאה לאותו API של המשתמש המאומת באמצעות פרמטר מחרוזת השאילתה access_token.

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

curl דוגמאות

אפשר לבדוק את הפקודות האלה באמצעות האפליקציה של שורת הפקודה curl. זוהי דוגמה לשימוש באפשרות 'כותרת HTTP' (מועדפת):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

לחלופין, אפשרות הפרמטר של מחרוזת שאילתה:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

כשאסימוני גישה פגים

אסימוני הגישה שהונפקו על ידי שרת ההרשאות של Google OAuth 2.0 יפוג לאחר משך הזמן שסופק על ידי הערך expires_in. כשפג התוקף של אסימון גישה, האפליקציה צריכה ליצור JWT נוסף, לחתום עליו ולבקש אסימון גישה נוסף.

קודי שגיאה של JWT

שדה error שדה error_description משמעות איך פותרים את הבעיה:
unauthorized_client Unauthorized client or scope in request. אם ניסית להשתמש בהענקת גישה ברמת הדומיין, חשבון השירות אינו מורשה במסוף הניהול של הדומיין של המשתמש.

יש לוודא שחשבון השירות מורשה בדף הענקת גישה ברמת הדומיין במסוף Admin למשתמש בתלונה (sub) בשדה.

האימות נמשך בדרך כלל כמה דקות, אבל ייתכן שיחלפו עד 24 שעות לפני שההרשאה תופץ לכל המשתמשים בחשבון Google שלך.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. חשבון השירות אושר באמצעות כתובת האימייל של הלקוח ולא באמצעות מספר הלקוח (מספר) במסוף Admin. בדף הענקת גישה ברמת הדומיין במסוף Admin, יש להסיר את הלקוח ולהוסיף אותו מחדש באמצעות המזהה המספרי.
access_denied (כל ערך) אם נעשה שימוש בהענקת גישה ברמת הדומיין, היקף הרשאה אחד או יותר אינו מורשה במסוף הניהול.

יש לוודא שחשבון השירות מורשה בדף הענקת גישה ברמת הדומיין של מסוף Admin של המשתמש בטענה sub (השדה), ושהיא כוללת את כל ההיקפים שביקשת בתביעה scope של ה-JWT.

האימות נמשך בדרך כלל כמה דקות, אבל ייתכן שיחלפו עד 24 שעות לפני שההרשאה תופץ לכל המשתמשים בחשבון Google שלך.

invalid_grant Not a valid email. המשתמש לא קיים. מוודאים שכתובת האימייל בsubתביעה (שדה) נכונה.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

בדרך כלל, המשמעות היא שזמן המערכת המקומי אינו נכון. יכול להיות גם שערך ה-exp יהיה יותר מ-65 דקות בעתיד מהערך iat, או שהערך של exp יהיה נמוך מהערך של iat.

מוודאים שהשעון במערכת שבו נוצר ה-JWT נכון. במידת הצורך, מומלץ לסנכרן את השעה עם Google NTP.

invalid_grant Invalid JWT Signature.

ההצהרה של JWT חתומה במפתח פרטי שאינו משויך לחשבון השירות שזוהה על ידי האימייל של הלקוח או שהמפתח שנעשה בו שימוש נמחק, הושבת או שפג תוקפו.

לחלופין, ייתכן שההצהרה של JWT מקודדת באופן שגוי – היא צריכה להיות בקידוד Base64, בלי שורות חדשות או מרווח פנימי זהה.

מפענחים את קבוצת התלונות של JWT ומוודאים שהמפתח שחתום על ההצהרה משויך לחשבון השירות.

כדי לוודא ש-JWT נוצר כראוי, אתם צריכים להשתמש בספריית OAuth שסופקה על ידי Google.

invalid_scope Invalid OAuth scope or ID token audience provided. לא התבקשו היקפים (רשימה ריקה של היקפים), או שאחד מההיקפים המבוקשים לא קיים (כלומר, לא חוקי).

יש לוודא שהscopeתלונה (שדה) של ה-JWT מאוכלסת, ולהשוות את ההיקפים שהיא כוללת עם ההיקפים המתועדים עבור ממשקי ה-API שבהם ברצונך להשתמש כדי לוודא שאין שגיאות או שגיאות הקלדה.

חשוב לשים לב שרשימת ההיקפים בתלונה scope צריכה להיות מופרדת ברווחים, לא בפסיקים.

disabled_client The OAuth client was disabled. המפתח המשמש לחתימה על הצהרת JWT מושבת.

נכנסים אל Google API Console, ובקטע IAM & Admin > חשבונות שירות, מפעילים את חשבון השירות שמכיל את ה-"Key Key" המשמש לחתימה על ההצהרה.

נספח: הרשאה לחשבון שירות ללא OAuth

בממשקי API מסוימים של Google, אפשר לבצע קריאות ל-API שאושרו באמצעות JWT חתום ישירות כאסימון, במקום אסימון גישה מסוג OAuth 2.0. כשהדבר אפשרי, ניתן להימנע משליחת בקשה לשרת ההרשאות של Google לפני ביצוע קריאה ל-API.

אם ה-API שברצונך להתקשר אליו פרסם הגדרת שירות במאגר ה-GitHub של Google APIs, ניתן לבצע קריאות ל-API מורשות באמצעות JWT במקום אסימון גישה. לשם כך:

  1. יוצרים חשבון שירות כפי שמתואר למעלה. חשוב לשמור את קובץ ה-JSON עם יצירת החשבון.
  2. באמצעות כל ספרייה של JWT רגילה, כמו זו שנמצאת בכתובת jwt.io, יוצרים JWT עם כותרת ומטען ייעודי (payload), כמו בדוגמה הבאה:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • בשדה kid בכותרת, צריך לציין את המזהה של חשבון השירות הפרטי&#39. אפשר למצוא את הערך הזה בשדה private_key_id של קובץ ה-JSON עם חשבון השירות.
    • בשדות iss ו-sub, יש לציין את כתובת האימייל של חשבון השירות שלך. אפשר למצוא את הערך הזה בשדה client_email של קובץ ה-JSON עם חשבון השירות.
    • בשדה aud, מציינים את נקודת הקצה של ה-API. לדוגמה: https://SERVICE.googleapis.com/.
    • בשדה iat, יש לציין את זמן היוניקס הנוכחי, ובשדה exp לציין את השעה המדויקת 3600 שניות מאוחר יותר, כשתאריך התפוגה של ה-JWT יפוג.

חותמים את ה-JWT באמצעות RSA-256 באמצעות המפתח הפרטי שנמצא בקובץ ה-JSON של חשבון השירות.

למשל:

Java

באמצעות google-api-Java-client ו- Java-jwt:

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

באמצעות PyJWT:

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. צריך להתקשר ל-API ולהשתמש ב-JWT החתום כאסימון של השרת.
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com