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

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

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

首先,创建一个服务帐户:

  1. 打开 Service accounts page
  2. If prompted, select a project, or create a new one.
  3. 单击创建服务帐户
  4. Service account details下,键入服务帐户的名称、ID 和描述,然后点击Create and continue
  5. 可选:在Grant this service account access to project下,选择要授予服务帐户的 IAM 角色。
  6. 单击继续
  7. 可选:在Grant users access to this service account下,添加允许使用和管理服务帐户的用户或组。
  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. מ מסוף Admin של הדומיין שלך ב-Google Workspace, עוברים אל תפריט ראשי > אבטחה > בקרת גישה ונתונים > בקרות 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 בתור משתמשים בדומיין שלך (כדי להתחזות למשתמשים). כשמתכוננים לבצע קריאות מורשות ל-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, ואז משתמשת באסימון כדי לקרוא לנקודת קצה (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, קבוצת תביעות 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. It should be the following (מעברי שורה נוספו כדי להבהיר):

{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 יש להשתמש במחרוזת הבאה, מקודדת לפי הצורך: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion ה-JWT, כולל חתימה.

זוהי דוגמה לקובץ Dump של בקשת POST מסוג HTTPS ששימשה בבקשת אסימון הגישה:

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

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

  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 בטא של 3 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

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

admin_policy_enforced (כל ערך) לחשבון Google אין הרשאה להעניק הרשאה להיקף הרשאות אחד לפחות, עקב המדיניות של האדמין ב-Google Workspace.

במאמר העזרה איך קובעים אילו אפליקציות של צדדים שלישיים ופנימיים יכולים לגשת לנתונים של Google Workspace?

invalid_client (כל ערך)

אסימון OAuth או אסימון JWT אינם חוקיים או שהם מוגדרים באופן שגוי.

פרטים נוספים מופיעים בתיאור השגיאה.

יש לוודא שאסימון ה-JWT חוקי וכולל תביעות נכונות.

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

יש לוודא שאסימון ה-JWT נכון והונפק עבור מספר הלקוח בבקשה.

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 Accounts, להפעיל את חשבון השירות שמכיל את "מזהה המפתח" המשמש לחתימה על ההצהרה.

org_internal This client is restricted to users within its organization. מספר הלקוח ב-OAuth בבקשה הוא חלק מפרויקט שמגביל את הגישה לחשבונות Google ב ארגון ספציפי של Google Cloud.

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

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

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

אם ממשק ה-API שאליו רוצים להתקשר פורסם על סמך הגדרת שירות במאגר ה-GitHub של ממשקי ה-API של Google, אפשר לבצע קריאות ל-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-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