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

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

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

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

First, create a service account:

  1. Open the Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. Click  Create service account.
  4. Under Service account details, type a name, ID, and description for the service account, then click Create and continue.
  5. Optional: Under Grant this service account access to project, select the IAM roles to grant to the service account.
  6. Click Continue.
  7. Optional: Under Grant users access to this service account, add the users or groups that are allowed to use and manage the service account.
  8. Click Done.
  9. Click  Create key, then click Create.

Next, create a service account key:

  1. Click the email address for the service account you created.
  2. Click the Keys tab.
  3. In the Add key drop-down list, select Create new key.
  4. Click Create.

Your new public/private key pair is generated and downloaded to your machine; it serves as the only copy of the private key. You are responsible for storing it securely. If you lose this key pair, you will need to generate a new one.

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

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

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

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

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

  1. במסוף Admin של Google Workspace, נכנסים לקטע תפריט ראשי > אבטחה > גישה לנתונים ולאמצעי בקרה > בקרות API.
  2. בחלונית הענקת גישה ברמת הדומיין, בוחרים באפשרות ניהול הענקת גישה ברמת הדומיין.
  3. לוחצים על הוספת חדש.
  4. בשדה Client-ID, מזינים את Service 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 בתור משתמשים בדומיין שלך (כדי להשתמש ב- " התחזות" משתמשים). כשמתכוננים לבצע קריאות ל-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')

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

HTTP/REST

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

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

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

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

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

אפליקציית השרת משתמשת ב-JWT כדי לבקש אסימון משרת ההרשאות של Google. לאחר מכן, הוא משתמש באסימון כדי להתקשר לנקודת קצה ב-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
יצירת קבוצת תלונות של WWT

קבוצת התלונות של 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
}
קידוד קבוצת התלונות של WWT

כמו כותרת JWT, סדרת התלונות של JWT צריכה להיות טורית לקידוד 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 Web Signature (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 חתום, אפליקציה יכולה להשתמש בו כדי לבקש אסימון גישה. בקשת אסימון הגישה הזו היא בקשת HTTPS מ-POST והגוף מקודד לפי כתובת URL. כתובת ה-URL מוצגת כך:

https://oauth2.googleapis.com/token

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

שם תיאור
grant_type צריך להשתמש במחרוזת הבאה ומקודדת לפי הצורך: 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

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

  1. יש לבנות אובייקט שירות עבור ה-API שאליו רוצים להתקשר. אפשר לבנות אובייקט שירות על ידי קריאה לפונקציה build עם השם והגרסה של ה-API ואובייקט Credentials המורשה. לדוגמה, כדי לקרוא לגרסה 1 בטא של ממשק API לניהול Cloud SQL:
    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 או ערך Bearer של כותרת HTTP מסוג Authorization. כשהדבר אפשרי, מומלץ להשתמש בכותרת 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 שעות, ייתכן שיחלפו עד 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.

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

תהליך האישור עשוי להימשך עד 24 שעות, ייתכן שיחלפו עד 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 ואימות המפתח שחתום על ההצהרה משויך לחשבון השירות.

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

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 > Service Account, מפעילים את חשבון השירות שמכיל את ה-"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 בכותרת, יש לציין את מזהה המפתח הפרטי של חשבון השירות. ניתן למצוא את הערך הזה בשדה private_key_id של קובץ ה-JSON עם חשבון השירות שלך.
    • בשדות iss ו-sub, יש לציין את כתובת האימייל של חשבון השירות שלך. ניתן למצוא את הערך הזה בשדה client_email של קובץ ה-JSON עם חשבון השירות שלך.
    • בשדה aud, מציינים את נקודת הקצה של ה-API. למשל: https://SERVICE.googleapis.com/.
    • בשדה iat, מציינים את השעה הנוכחית ב-Unix, ובשדה exp, מציינים את השעה במדויק 3600 שניות, כשהתוקף של JWT פג.

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

למשל:

Java

משתמשים ב- google-api-javascript-client וב-JavaScript-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