שימוש ב-OAuth 2.0 לאפליקציות אינטרנט

מסמך זה מסביר איך אפליקציות שרת אינטרנט משתמשות בספריות לקוח של Google API או בנקודות קצה (endpoint) של Google OAuth 2.0 כדי להטמיע הרשאת OAuth 2.0 כדי לגשת אל Google APIs.

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

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

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

ספריות לקוח

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

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

ספריות לקוח של Google API לאפליקציות בצד השרת זמינות בשפות הבאות:

דרישות מוקדמות

הפעלת ממשקי API בפרויקט

כל אפליקציה קוראת ל-Google APIs צריכה להפעיל את ממשקי ה-API האלה ב- API Console.

כדי להפעיל API לפרויקט:

  1. Open the API Library ב Google API Console.
  2. If prompted, select a project, or create a new one.
  3. רשימה של API Library כל ממשקי ה-API הזמינים, המקובצים לפי משפחת מוצרים ופופולריות. אם ה-API שרוצים להפעיל לא מופיע ברשימה, מחפשים אותו או לוחצים על הצגת הכול במשפחת המוצרים שאליה הוא שייך.
  4. בוחרים את ה-API שרוצים להפעיל ולוחצים על הלחצן הפעלה.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

יצירת פרטי כניסה של הרשאה

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

  1. Go to the Credentials page.
  2. לוחצים על יצירת פרטי כניסה > מזהה לקוח ב-OAuth.
  3. בוחרים בסוג האפליקציה אפליקציית אינטרנט.
  4. ממלאים את הטופס ולוחצים על יצירה. באפליקציות שמשתמשות בשפות ובמסגרות כמו PHP, Java, Python, Ruby ו- .NET, יש לציין URI של כתובות URL להפניה מחדש. ה-URI של ההפניות האוטומטיות הן נקודות הקצה ששרת OAuth 2.0 יכול לשלוח להן תשובות. נקודות הקצה האלה חייבות לעמוד בכללי האימות של Google.

    לצורך בדיקה, אפשר לציין URI שמתייחסות למכונה המקומית, למשל http://localhost:8080. חשוב לזכור שכל הדוגמאות במסמך הזה כוללות את http://localhost:8080 כ-URI של הפניה אוטומטית.

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

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

זיהוי היקפי גישה

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

לפני שמתחילים ליישם את ההרשאה של OAuth 2.0, מומלץ לזהות את ההיקפים שהאפליקציה שלך תצטרך עבורם הרשאת גישה.

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

המסמך OAuth 2.0 API Scopes מכיל רשימה מלאה של היקפים שניתן להשתמש בהם כדי לגשת אל Google APIs.

דרישות ספציפיות לשפה

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

PHP

כדי להריץ דוגמאות של קוד PHP במסמך הזה, צריך:

  • PHP 5.4 ואילך עם ממשק שורת פקודה (CLI) ותוסף JSON מותקנים.
  • הכלי לניהול תלות של מחבר.
  • ספריית הלקוחות של Google APIs ל-PHP:

    php composer.phar require google/apiclient:^2.0

Python

כדי להריץ דוגמאות של קוד Python במסמך הזה, צריך:

  • Python מגרסה 2.6 ואילך
  • הכלי pip לניהול חבילות.
  • ספריית הלקוחות של Google APIs ל-Python:
    pip install --upgrade google-api-python-client
  • google-auth, google-auth-oauthlib, ו-google-auth-httplib2 להרשאת משתמש.
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • מסגרת של יישום האינטרנט של Flask.
    pip install --upgrade flask
  • ספריית requests של HTTP.
    pip install --upgrade requests

Ruby

כדי להריץ דוגמאות של קוד Ruby במסמך הזה, צריך:

  • רובי 2.2.2 ומעלה
  • ספריית הלקוחות של Google APIs עבור Ruby:

    gem install google-api-client
  • המסגרת של סינאטה רובי באינטרנט.

    gem install sinatra

Node.js

כדי להפעיל את הדוגמאות של קוד Node.js במסמך הזה, צריך:

  • ה-LTS התחזוקתי, LTS פעיל או הגרסה הנוכחית של Node.js.
  • לקוח Node.js של Google APIs:

    npm install googleapis

HTTP/REST

אין צורך להתקין ספריות כדי שניתן יהיה להתקשר ישירות לנקודות הקצה של OAuth 2.0.

קבלת אסימוני גישה של OAuth 2.0

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

הרשימה הבאה מסכמת במהירות את השלבים הבאים:

  1. האפליקציה מזהה את ההרשאות הדרושות.
  2. האפליקציה מפנה את המשתמש ל-Google יחד עם רשימת ההרשאות הנדרשות.
  3. המשתמש מחליט אם להעניק את ההרשאות לאפליקציה שלך.
  4. האפליקציה מזהה מה המשתמש החליט.
  5. אם המשתמש העניק את ההרשאות הנדרשות, האפליקציה שלך מאחזרת אסימונים הנדרשים לביצוע בקשות API בשם המשתמש.

שלב 1: מגדירים פרמטרים של הרשאה

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

  • אם בחרת להשתמש בספריית לקוח ב-Google לאימות ולהרשאה של OAuth 2.0, עליך ליצור ולהגדיר אובייקט שמגדיר את הפרמטרים האלה.
  • אם מתקשרים ישירות לנקודת הקצה של Google OAuth 2.0, צריך ליצור כתובת URL ולהגדיר את הפרמטרים בכתובת ה-URL הזו.

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

PHP

קטע הקוד שמופיע בהמשך יוצר אובייקט Google_Client(), שמגדיר את הפרמטרים בבקשת ההרשאה.

אובייקט זה משתמש במידע מתוך קובץ ה-client_Secret.json שלך כדי לזהות את האפליקציה שלך. (מידע נוסף זמין במאמר יצירת פרטי כניסה להרשאות). האובייקט גם מזהה את ההיקפים שאליהם האפליקציה שלך מבקשת הרשאת גישה, ואת כתובת ה-URL אל נקודת הקצה לאימות של האפליקציה שלך, שמטפלת בתגובה משרת OAuth 2.0 של Google. לבסוף, הקוד מגדיר את הפרמטרים האופציונליים access_type ו-include_granted_scopes.

לדוגמה, הקוד הזה מבקש הרשאת קריאה בלבד במצב אופליין ל-Google Drive:

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true);   // incremental auth

הבקשה מציינת את הפרטים הבאים:

פרמטרים
client_id נדרש

מזהה הלקוח של האפליקציה. ניתן למצוא את הערך הזה ב- API Console Credentials page.

ב-PHP, יש לקרוא לפונקציה setAuthConfig כדי לטעון פרטי כניסה מתוך קובץ client_secret.json.

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
redirect_uri נדרש

קביעת המיקום שבו שרת ה-API יפנה את המשתמש לאחר השלמת תהליך ההרשאה. הערך חייב להיות זהה לאחד ממזהי ה-URI המורשים של לקוח OAuth 2.0, שאותו הגדרת ללקוח שלך ב- API Console. Credentials page. אם הערך הזה לא תואם ל-URI המותר של הפניה אוטומטית עבור client_id שצוינו, תתקבל שגיאת redirect_uri_mismatch.

הערה: http או הhttps הסכימה, הפנייה והקו הנטוי האחרון ('/') חייבים להיות תואמים.

כדי להגדיר את הערך הזה ב-PHP, צריך לקרוא לפונקציה setRedirectUri. חשוב לזכור שצריך לציין URI תקין להפניה אוטומטית עבור client_id שצוין.

$client->setRedirectUri('https://oauth2.example.com/code');
scope נדרש

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

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

כדי להגדיר את הערך הזה ב-PHP, צריך לקרוא לפונקציה addScope:

$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);

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

access_type מומלץ

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

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

כדי להגדיר את הערך הזה ב-PHP, צריך לקרוא לפונקציה setAccessType:

$client->setAccessType('offline');
state מומלץ

מציין את ערך המחרוזת שמשמש את האפליקציה כדי לשמור על מצב בין בקשת ההרשאה שלך לבין תגובת שרת ההרשאות. השרת מחזיר את הערך המדויק ששלחת כצמד name=value ברכיב השאילתה של כתובת ה-URL (?) של redirect_uri אחרי שהמשתמש מסכים או לא מאשר את בקשת הגישה של האפליקציה.

ניתן להשתמש בפרמטר הזה בכמה מטרות, כמו הפניית המשתמש למשאב הנכון באפליקציה, שליחת צפנים חד-פעמיים וצמצום בקשות בין אתרים. מאחר שניתן לנחש את redirect_uri שלך, שימוש בערך state יכול להגביר את ההבטחה שחיבור נכנס הוא תוצאה של בקשת אימות. אם יוצרים מחרוזת אקראית או מקודדים גיבוב (hash) של קובץ cookie או ערך אחר שמתעד את מצב הלקוח, ניתן לאמת את התגובה בנוסף כדי לוודא שהבקשה והתגובה הגיעו באותו דפדפן, כהגנה מפני התקפות כמו זיוף בקשות בין אתרים. כדי לראות דוגמה ליצירת אסימון 'state' ואישורו יש לעיין בתיעוד של OpenID Connect.

כדי להגדיר את הערך הזה ב-PHP, צריך לקרוא לפונקציה setState:

$client->setState($sample_passthrough_value);
include_granted_scopes אופציונלי

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

כדי להגדיר את הערך הזה ב-PHP, צריך לקרוא לפונקציה setIncludeGrantedScopes:

$client->setIncludeGrantedScopes(true);
login_hint אופציונלי

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

הגדרה של ערך הפרמטר לכתובת אימייל או למזהה sub, שזהה למזהה Google של המשתמש.

כדי להגדיר את הערך הזה ב-PHP, צריך לקרוא לפונקציה setLoginHint:

$client->setLoginHint('None');
prompt אופציונלי

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

כדי להגדיר את הערך הזה ב-PHP, צריך לקרוא לפונקציה setApprovalPrompt:

$client->setApprovalPrompt('consent');

הערכים האפשריים הם:

none אין להציג מסכי אימות או הסכמה. אין לציין אותם עם ערכים אחרים.
consent צריך לבקש מהמשתמש הסכמה.
select_account מבקשים מהמשתמש לבחור חשבון.

Python

קטע הקוד הבא משתמש במודול google-auth-oauthlib.flow כדי ליצור את בקשת ההרשאה.

הקוד יוצר אובייקט Flow, שמזהה את האפליקציה שלך באמצעות מידע מהקובץ client_Secret.json שהורדת אחרי יצירת פרטי הכניסה להרשאה. אובייקט זה מזהה גם את ההיקפים שהאפליקציה שלך מבקשת הרשאה לגשת אליהם, ואת כתובת ה-URL אל נקודת הקצה של האפליקציה שלך, שיטפלה בתגובה משרת OAuth 2.0 של Google. לבסוף, הקוד מגדיר את הפרמטרים האופציונליים access_type ו-include_granted_scopes.

לדוגמה, הקוד הזה מבקש הרשאת קריאה בלבד במצב אופליין ל-Google Drive:

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Use the client_secret.json file to identify the application requesting
# authorization. The client ID (from that file) and access scopes are required.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'

# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
    # Enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    # Enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true')

הבקשה מציינת את הפרטים הבאים:

פרמטרים
client_id נדרש

מזהה הלקוח של האפליקציה. ניתן למצוא את הערך הזה ב- API Console Credentials page.

ב-Python, קוראים לשיטה from_client_secrets_file כדי לאחזר את מזהה הלקוח מקובץ client_secret.json. (ניתן גם להשתמש בשיטת from_client_config, שמעבירים את תצורת הלקוח כפי שהיא הופיעה במקור בקובץ סודות של לקוח, אבל לא מתבצעת גישה לקובץ עצמו).

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])
redirect_uri נדרש

קביעת המיקום שבו שרת ה-API יפנה את המשתמש לאחר השלמת תהליך ההרשאה. הערך חייב להיות זהה לאחד ממזהי ה-URI המורשים של לקוח OAuth 2.0, שאותו הגדרת ללקוח שלך ב- API Console. Credentials page. אם הערך הזה לא תואם ל-URI המותר של הפניה אוטומטית עבור client_id שצוינו, תתקבל שגיאת redirect_uri_mismatch.

הערה: http או הhttps הסכימה, הפנייה והקו הנטוי האחרון ('/') חייבים להיות תואמים.

כדי להגדיר את הערך הזה ב-Python, מגדירים את המאפיין redirect_uri באובייקט flow &:

flow.redirect_uri = 'https://oauth2.example.com/code'
scope נדרש

רשימה של היקפי הרשאות שמזהים את המשאבים שהאפליקציה שלך יכולה לגשת אליהם בשם המשתמש. הערכים האלה מיידעים את מסך ההסכמה ש-Google מציגה למשתמש.

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

ב-Python, משתמשים באותה שיטה שבה משתמשים כדי להגדיר את client_id כדי לציין את רשימת ההיקפים.

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

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

access_type מומלץ

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

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

ב-Python, מגדירים את הפרמטר access_type על ידי ציון access_type כארגומנט של מילות מפתח כשמפעילים את השיטה flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
state מומלץ

מציין את ערך המחרוזת שמשמש את האפליקציה כדי לשמור על מצב בין בקשת ההרשאה שלך לבין תגובת שרת ההרשאות. השרת מחזיר את הערך המדויק ששלחת כצמד name=value ברכיב השאילתה של כתובת ה-URL (?) של redirect_uri אחרי שהמשתמש מסכים או לא מאשר את בקשת הגישה של האפליקציה.

ניתן להשתמש בפרמטר הזה בכמה מטרות, כמו הפניית המשתמש למשאב הנכון באפליקציה, שליחת צפנים חד-פעמיים וצמצום בקשות בין אתרים. מאחר שניתן לנחש את redirect_uri שלך, שימוש בערך state יכול להגביר את ההבטחה שחיבור נכנס הוא תוצאה של בקשת אימות. אם יוצרים מחרוזת אקראית או מקודדים גיבוב (hash) של קובץ cookie או ערך אחר שמתעד את מצב הלקוח, ניתן לאמת את התגובה בנוסף כדי לוודא שהבקשה והתגובה הגיעו באותו דפדפן, כהגנה מפני התקפות כמו זיוף בקשות בין אתרים. כדי לראות דוגמה ליצירת אסימון 'state' ואישורו יש לעיין בתיעוד של OpenID Connect.

ב-Python, מגדירים את הפרמטר state על ידי ציון state כארגומנט של מילות מפתח במהלך קריאה לשיטה flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    state=sample_passthrough_value,
    include_granted_scopes='true')
include_granted_scopes אופציונלי

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

ב-Python, מגדירים את הפרמטר include_granted_scopes על ידי ציון include_granted_scopes כארגומנט של מילות מפתח כשמפעילים את השיטה flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
login_hint אופציונלי

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

הגדרה של ערך הפרמטר לכתובת אימייל או למזהה sub, שזהה למזהה Google של המשתמש.

ב-Python, מגדירים את הפרמטר login_hint על ידי ציון login_hint כארגומנט של מילות מפתח כשמפעילים את השיטה flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    login_hint='None',
    include_granted_scopes='true')
prompt אופציונלי

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

ב-Python, מגדירים את הפרמטר prompt על ידי ציון prompt כארגומנט של מילות מפתח במהלך קריאה לשיטה flow.authorization_url:

authorization_url, state = flow.authorization_url(
      access_type='offline',
      prompt='consent',
      include_granted_scopes='true')

הערכים האפשריים הם:

none אין להציג מסכי אימות או הסכמה. אין לציין אותם עם ערכים אחרים.
consent צריך לבקש מהמשתמש הסכמה.
select_account מבקשים מהמשתמש לבחור חשבון.

Ruby

יש להשתמש בקובץ client_secrets.json שיצרת כדי להגדיר אובייקט לקוח באפליקציה. כשמגדירים אובייקט לקוח, צריך לציין את ההיקפים שאליהם האפליקציה תצטרך לגשת, וכן את כתובת ה-URL של נקודת הקצה של האפליקציה, שתטפל בתגובה משרת OAuth 2.0.

לדוגמה, הקוד הזה מבקש הרשאת קריאה בלבד במצב אופליין ל-Google Drive:

require 'google/apis/drive_v2'
require 'google/api_client/client_secrets'

client_secrets = Google::APIClient::ClientSecrets.load
auth_client = client_secrets.to_authorization
auth_client.update!(
  :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
  :redirect_uri => 'http://www.example.com/oauth2callback',
  :additional_parameters => {
    "access_type" => "offline",         # offline access
    "include_granted_scopes" => "true"  # incremental auth
  }
)

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

Node.js

קטע הקוד שמופיע בהמשך יוצר אובייקט google.auth.OAuth2, שמגדיר את הפרמטרים בבקשת ההרשאה.

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

const {google} = require('googleapis');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
 * from the client_secret.json file. To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true
});

הערה חשובהrefresh_token מוחזר רק באישור הראשון. פרטים נוספים כאן.

HTTP/REST

נקודת הקצה של OAuth 2.0 של Google נמצאת ב-https://accounts.google.com/o/oauth2/v2/auth. נקודת הקצה הזו נגישה רק דרך HTTPS. נדחו חיבורי HTTP פשוטים.

שרת ההרשאות של Google תומך בפרמטרים הבאים של מחרוזת שאילתה באפליקציות שרת אינטרנט:

פרמטרים
client_id נדרש

מזהה הלקוח של האפליקציה. ניתן למצוא את הערך הזה ב- API Console Credentials page.

redirect_uri נדרש

קביעת המיקום שבו שרת ה-API יפנה את המשתמש לאחר השלמת תהליך ההרשאה. הערך חייב להיות זהה לאחד ממזהי ה-URI המורשים של לקוח OAuth 2.0, שאותו הגדרת ללקוח שלך ב- API Console. Credentials page. אם הערך הזה לא תואם ל-URI המותר של הפניה אוטומטית עבור client_id שצוינו, תתקבל שגיאת redirect_uri_mismatch.

הערה: http או הhttps הסכימה, הפנייה והקו הנטוי האחרון ('/') חייבים להיות תואמים.

response_type נדרש

המדיניות קובעת אם נקודת הקצה של Google OAuth 2.0 מחזירה קוד הרשאה.

יש להגדיר את ערך הפרמטר כ-code לאפליקציות של שרת האינטרנט.

scope נדרש

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

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

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

access_type מומלץ

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

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

state מומלץ

מציין את ערך המחרוזת שמשמש את האפליקציה כדי לשמור על מצב בין בקשת ההרשאה שלך לבין תגובת שרת ההרשאות. השרת מחזיר את הערך המדויק ששלחת כצמד name=value ברכיב השאילתה של כתובת ה-URL (?) של redirect_uri אחרי שהמשתמש מסכים או לא מאשר את בקשת הגישה של האפליקציה.

ניתן להשתמש בפרמטר הזה בכמה מטרות, כמו הפניית המשתמש למשאב הנכון באפליקציה, שליחת צפנים חד-פעמיים וצמצום בקשות בין אתרים. מאחר שניתן לנחש את redirect_uri שלך, שימוש בערך state יכול להגביר את ההבטחה שחיבור נכנס הוא תוצאה של בקשת אימות. אם יוצרים מחרוזת אקראית או מקודדים גיבוב (hash) של קובץ cookie או ערך אחר שמתעד את מצב הלקוח, ניתן לאמת את התגובה בנוסף כדי לוודא שהבקשה והתגובה הגיעו באותו דפדפן, כהגנה מפני התקפות כמו זיוף בקשות בין אתרים. כדי לראות דוגמה ליצירת אסימון 'state' ואישורו יש לעיין בתיעוד של OpenID Connect.

include_granted_scopes אופציונלי

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

login_hint אופציונלי

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

הגדרה של ערך הפרמטר לכתובת אימייל או למזהה sub, שזהה למזהה Google של המשתמש.

prompt אופציונלי

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

הערכים האפשריים הם:

none אין להציג מסכי אימות או הסכמה. אין לציין אותם עם ערכים אחרים.
consent צריך לבקש מהמשתמש הסכמה.
select_account מבקשים מהמשתמש לבחור חשבון.

שלב 2: הפניה אוטומטית לשרת OAuth 2.0 של Google

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

PHP

  1. יצירת כתובת URL לבקשת גישה משרת OAuth 2.0 של Google:
    $auth_url = $client->createAuthUrl();
  2. הפניית המשתמש אל $auth_url:
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

בדוגמה הבאה אפשר לראות איך להפנות את המשתמשים לכתובת ה-URL של ההרשאה באמצעות מסגרת של אפליקציית Websk:

return flask.redirect(authorization_url)

Ruby

  1. יצירת כתובת URL לבקשת גישה משרת OAuth 2.0 של Google:
    auth_uri = auth_client.authorization_uri.to_s
  2. הפניית המשתמש אל auth_uri.

Node.js

  1. יש להשתמש בכתובת ה-URL שנוצרה authorizationUrl משיטת שלב 1 generateAuthUrl כדי לבקש גישה משרת OAuth 2.0 של Google.
  2. הפניית המשתמש אל authorizationUrl.
    res.writeHead(301, { "Location": authorizationUrl });

HTTP/REST

Sample redirect to Google's authorization server

An example URL is shown below, with line breaks and spaces for readability.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

אחרי שיוצרים את כתובת ה-URL של הבקשה, מפנים את המשתמש אליה.

שרת OAuth 2.0 של Google מאמת את המשתמש ומקבל את הסכמתו עבור האפליקציה שלך כדי לגשת להיקפים המבוקשים. התגובה תישלח חזרה לאפליקציה באמצעות כתובת ה-URL להפניה אוטומטית שציינת.

שלב 3: Google מבקשת את הסכמת המשתמש

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

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

שגיאות

בבקשות לנקודת הקצה של OAuth 2.0 OAuth עשויות להופיע הודעות שגיאה שמוצגות למשתמשים במקום לתהליך האימות והתהליך הצפוי. קודי שגיאה נפוצים והפתרונות המוצעים מפורטים בהמשך.

admin_policy_enforced

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

disallowed_useragent

נקודת הקצה להרשאה מוצגת בסוכן משתמש מוטמע שאסור להשתמש בו במדיניות של OAuth 2.0.

Android

מפתחי Android עשויים להיתקל בהודעת השגיאה הזו בעת פתיחת בקשות הרשאה בandroid.webkit.WebView. במקום זאת, מפתחים צריכים להשתמש בספריות Android, כמו כניסה באמצעות חשבון Google ל-Android או OpenID Fund's AppAuth for Android.

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

iOS

מפתחים של iOS ו-macOS עשויים להיתקל בשגיאה הזו כשפותחים בקשות הרשאה בWKWebView. במקום זאת, מפתחים צריכים להשתמש בספריות iOS, כמו כניסה באמצעות חשבון Google ל-iOS או OpenID Fundamentals's ל-iOS.

מפתחי אתרים עשויים להיתקל בשגיאה הזו כשאפליקציית iOS או macOS פותחת קישור אינטרנט כללי בסוכן משתמש מוטמע, ומשתמש מנווט אל נקודת הקצה של OAuth בפרוטוקול 2.0 של Google באתר שלך. מפתחים צריכים לאפשר לקישורים הכלליים להיפתח ב-handler של ברירת המחדל לקישורים של מערכת ההפעלה, הכולל גם את רכיבי ה-handler של קישורים אוניברסליים או את אפליקציית ברירת המחדל של הדפדפן. גם האפשרות SFSafariViewController נתמכת.

org_internal

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

redirect_uri_mismatch

ה-redirect_uri שהועבר בבקשת ההרשאה לא תואם ל-URI המורשה להפניה מחדש עבור מספר הלקוח ב-OAuth. יש לבדוק את ה-URI מורשים להפניה מחדש ב Google API Console Credentials page.

שלב 4: טיפול בתגובת שרת OAuth 2.0

שרת OAuth 2.0 מגיב לבקשת הגישה של האפליקציה שלך באמצעות כתובת ה-URL שצוינה בבקשה.

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

תגובת שגיאה:

https://oauth2.example.com/auth?error=access_denied

תגובה של קוד הרשאה:

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

דוגמה לתגובה של שרת OAuth 2.0

כדי לבדוק את התהליך הזה, לוחצים על כתובת ה-URL לדוגמה הבאה, המבקשת גישת קריאה בלבד להצגת מטא-נתונים של קבצים ב-Google Drive:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

אחרי השלמת התהליך של OAuth 2.0, המערכת תפנה אותך אל http://localhost/oauth2callback, שסביר להניח שתוביל שגיאה של 404 NOT FOUND אלא אם המכונה המקומית שלך תציג קובץ בכתובת הזו. השלב הבא כולל פרטים נוספים על המידע שהוחזר ב-URI כשהמשתמש מופנה חזרה לאפליקציה שלך.

שלב 5: החלפת קוד הרשאה עבור רענון וגישה לאסימונים

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

PHP

כדי להחליף קוד הרשאה של אסימון גישה, יש להשתמש בשיטה authenticate:

$client->authenticate($_GET['code']);

אפשר לאחזר את אסימון הגישה בשיטה getAccessToken:

$access_token = $client->getAccessToken();

Python

בדף השיחה החוזרת, יש להשתמש בספרייה google-auth כדי לאמת את התשובה לשרת ההרשאות. לאחר מכן, יש להשתמש בשיטה flow.fetch_token כדי להחליף את קוד ההרשאה בתגובה הזו באסימון גישה:

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],
    state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in the session.
# ACTION ITEM for developers:
#     Store user's access and refresh tokens in your data store if
#     incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'scopes': credentials.scopes}

Ruby

כדי להחליף קוד הרשאה של אסימון גישה, יש להשתמש בשיטה fetch_access_token!:

auth_client.code = auth_code
auth_client.fetch_access_token!

Node.js

כדי להחליף קוד הרשאה של אסימון גישה, יש להשתמש בשיטה getToken:

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
if (req.url.startsWith('/oauth2callback')) {
  // Handle the OAuth 2.0 server response
  let q = url.parse(req.url, true).query;

  // Get access and refresh tokens (if access_type is offline)
  let { tokens } = await oauth2Client.getToken(q.code);
  oauth2Client.setCredentials(tokens);
}

HTTP/REST

כדי להחליף את קוד ההרשאה של אסימון הגישה, יש להתקשר אל נקודת הקצה של https://oauth2.googleapis.com/token ולהגדיר את הפרמטרים הבאים:

שדות
client_id מספר הלקוח שהתקבל מה- API Console Credentials page.
client_secret סוד הלקוח שהתקבל מה- API Console Credentials page.
code קוד ההרשאה הוחזר מהבקשה הראשונית.
grant_type כפי שמוגדר במפרט של OAuth 2.0, יש להגדיר את הערך של השדה הזה כ-authorization_code.
redirect_uri אחד ממזהי ה-URI הרשומים עבור הפרויקט שלך ב- API Console Credentials page עבור client_id הנתון.

בקטע הבא מוצגת בקשה לדוגמה:

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

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

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

התגובה מכילה את השדות הבאים:

שדות
access_token האסימון שהאפליקציה שלך שולחת כדי לאשר בקשת Google API.
expires_in משך החיים הנותרים של אסימון הגישה בשניות.
refresh_token אסימון שניתן להשתמש בו כדי לקבל אסימון גישה חדש. אסימוני הרענון יהיו בתוקף עד שהמשתמש יבטל את הגישה. שוב, השדה הזה יוצג בתגובה הזו רק אם תגדיר את הפרמטר access_type כ-offline בבקשה הראשונית לשרת ההרשאות של Google.
scope היקפי הגישה שהוענקו על ידי access_token מבוטאים כרשימה של מחרוזות תלויות-רווחים.
token_type סוג האסימון הוחזר. נכון לעכשיו, הערך של השדה הזה תמיד מוגדר Bearer.

בקטע הבא מוצגת דוגמה לתגובה:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

קריאה ל-Google APIs

PHP

יש להשתמש באסימון הגישה כדי להתקשר אל Google APIs על ידי ביצוע השלבים הבאים:

  1. אם עליך להחיל אסימון גישה על אובייקט Google_Client חדש — לדוגמה, אם שמרת את אסימון הגישה בסשן של משתמש — יש להשתמש בשיטה setAccessToken:
    $client->setAccessToken($access_token);
  2. יש לבנות אובייקט שירות עבור ה-API שאליו רוצים להתקשר. יש לבנות אובייקט שירות על ידי ציון אובייקט Google_Client מורשה לבנייה של ה-API שאליו ברצונך להתקשר. לדוגמה, כדי לקרוא ל-Drive API:
    $drive = new Google_Service_Drive($client);
  3. שולחים בקשות לשירות ה-API באמצעות הממשק שסופק על ידי האובייקט של השירות. לדוגמה, כדי לרשום את הקבצים ב-Google Drive של המשתמש המאומת:
    $files = $drive->files->listFiles(array())->getItems();

Python

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

  1. יש לבנות אובייקט שירות עבור ה-API שאליו רוצים להתקשר. כדי ליצור אובייקט שירות, צריך לקרוא לשיטה build של "googleapiclient.discovery" בשם ובגרסה של ה-API ופרטי הכניסה של המשתמש: לדוגמה, כדי להתקשר לגרסה 2 של ממשק ה-API של Drive:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. שולחים בקשות לשירות ה-API באמצעות הממשק שסופק על ידי האובייקט של השירות. לדוגמה, כדי לרשום את הקבצים ב-Google Drive של המשתמש המאומת:
    files = drive.files().list().execute()

Ruby

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

  1. יש לבנות אובייקט שירות עבור ה-API שאליו רוצים להתקשר. לדוגמה, כדי לקרוא לגרסה 2 של Drive API:
    drive = Google::Apis::DriveV2::DriveService.new
  2. מגדירים את פרטי הכניסה בשירות:
    drive.authorization = auth_client
  3. שולחים בקשות לשירות ה-API באמצעות הממשק שסופק על ידי האובייקט של השירות. לדוגמה, כדי לרשום את הקבצים ב-Google Drive המאומת של המשתמש:
    files = drive.list_files

לחלופין, אפשר לתת הרשאה לכל שיטה על ידי ציון הפרמטר options לשיטה:

files = drive.list_files(options: { authorization: auth_client })

Node.js

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

const { google } = require('googleapis');

// Example of using Google Drive API to list filenames in user's Drive.
const drive = google.drive('v3');
drive.files.list({
  auth: oauth2Client,
  pageSize: 10,
  fields: 'nextPageToken, files(id, name)',
}, (err1, res1) => {
  if (err1) return console.log('The API returned an error: ' + err1);
  const files = res1.data.files;
  if (files.length) {
    console.log('Files:');
    files.map((file) => {
      console.log(`${file.name} (${file.id})`);
    });
  } else {
    console.log('No files found.');
  }
});

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

השלמת הדוגמה

בדוגמה הבאה מוצגת רשימה של קבצים בפורמט JSON ב-Google Drive של משתמשים אחרי שהמשתמש מאמת את החשבון ומאשר לאפליקציה לקבל גישה למטא-נתונים של משתמש ב-Drive.

PHP

כדי להציג דוגמה זו:

  1. ב- API Console, יש להוסיף את כתובת ה-URL של המכונה המקומית לרשימת כתובות ה-URL של ההפניה האוטומטית. לדוגמה, יש להוסיף http://localhost:8080.
  2. יצירת ספרייה חדשה והחלפה אליה. למשל:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. אפשר להתקין את ספריית הלקוח של Google API עבור PHP באמצעות מלחין:
    composer require google/apiclient:^2.0
  4. יש ליצור את הקבצים index.php ו-oauth2callback.php עם התוכן שבהמשך.
  5. הרצת הדוגמה עם שרת אינטרנט המוגדר להצגת PHP. אם משתמשים בגרסה PH5.4 ואילך, אפשר להשתמש בשרת האינטרנט המובנה של PHP&#39:
    php -S localhost:8080 ~/php-oauth2-example

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google_Client();
$client->setAuthConfig('client_secrets.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $drive = new Google_Service_Drive($client);
  $files = $drive->files->listFiles(array())->getItems();
  echo json_encode($files);
} else {
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

oauth2callback.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);

if (! isset($_GET['code'])) {
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Python

בדוגמה הזו נעשה שימוש במסגרת Flask. המערכת מפעילה אפליקציית אינטרנט בכתובת http://localhost:8080 שמאפשרת לך לבדוק את תהליך OAuth 2.0. אם עוברים לכתובת ה-URL הזו, אמורים להופיע ארבעה קישורים:

  • בדיקת בקשה ל-API: הקישור הזה מפנה לדף שמנסה להפעיל בקשת API לדוגמה. אם צריך, מתחיל תהליך ההרשאה. אם התגובה לבקשה מוצלחת, הדף מציג את תגובת ה-API.
  • בדיקה ישירה של תהליך האימות: קישור זה מפנה לדף שמנסה לשלוח את המשתמש דרך תהליך ההרשאה. האפליקציה מבקשת הרשאה לשלוח בקשות API מורשות בשם המשתמש.
  • ביטול פרטי הכניסה הנוכחיים: הקישור הזה מפנה לדף ש מבטל הרשאות שהמשתמש כבר העניק לאפליקציה.
  • ניקוי פרטי כניסה לסשן משנה: הקישור הזה מנקה פרטי כניסה המאוחסנים בסשן בקבוקון. כך אפשר לראות מה יקרה אם משתמש שכבר נתן הרשאה לאפליקציה שלך ינסה לבצע בקשת API בסשן חדש. היא גם מאפשרת לך לראות את התגובה של ה-API שהאפליקציה שלך תקבל אם משתמש ביטל את ההרשאות שהוענקו לה באפליקציה. האפליקציה עדיין תנסה לאשר בקשה באמצעות אסימון גישה שבוטל.
# -*- coding: utf-8 -*-

import os
import flask
import requests

import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
API_SERVICE_NAME = 'drive'
API_VERSION = 'v2'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'


@app.route('/')
def index():
  return print_index_table()


@app.route('/test')
def test_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  # Load credentials from the session.
  credentials = google.oauth2.credentials.Credentials(
      **flask.session['credentials'])

  drive = googleapiclient.discovery.build(
      API_SERVICE_NAME, API_VERSION, credentials=credentials)

  files = drive.files().list().execute()

  # Save credentials back to session in case access token was refreshed.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.jsonify(**files)


@app.route('/authorize')
def authorize():
  # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES)

  # The URI created here must exactly match one of the authorized redirect URIs
  # for the OAuth 2.0 client, which you configured in the API Console. If this
  # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
  # error.
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

  # Store the state so the callback can verify the auth server response.
  flask.session['state'] = state

  return flask.redirect(authorization_url)


@app.route('/oauth2callback')
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = flask.session['state']

  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = flask.request.url
  flow.fetch_token(authorization_response=authorization_response)

  # Store credentials in the session.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  credentials = flow.credentials
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.redirect(flask.url_for('test_api_request'))


@app.route('/revoke')
def revoke():
  if 'credentials' not in flask.session:
    return ('You need to <a href="/authorize">authorize</a> before ' +
            'testing the code to revoke credentials.')

  credentials = google.oauth2.credentials.Credentials(
    **flask.session['credentials'])

  revoke = requests.post('https://oauth2.googleapis.com/revoke',
      params={'token': credentials.token},
      headers = {'content-type': 'application/x-www-form-urlencoded'})

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())


@app.route('/clear')
def clear_credentials():
  if 'credentials' in flask.session:
    del flask.session['credentials']
  return ('Credentials have been cleared.<br><br>' +
          print_index_table())


def credentials_to_dict(credentials):
  return {'token': credentials.token,
          'refresh_token': credentials.refresh_token,
          'token_uri': credentials.token_uri,
          'client_id': credentials.client_id,
          'client_secret': credentials.client_secret,
          'scopes': credentials.scopes}

def print_index_table():
  return ('<table>' +
          '<tr><td><a href="/test">Test an API request</a></td>' +
          '<td>Submit an API request and see a formatted JSON response. ' +
          '    Go through the authorization flow if there are no stored ' +
          '    credentials for the user.</td></tr>' +
          '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
          '<td>Go directly to the authorization flow. If there are stored ' +
          '    credentials, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
          '<td>Revoke the access token associated with the current user ' +
          '    session. After revoking credentials, if you go to the test ' +
          '    page, you should see an <code>invalid_grant</code> error.' +
          '</td></tr>' +
          '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
          '<td>Clear the access token currently stored in the user session. ' +
          '    After clearing the token, if you <a href="/test">test the ' +
          '    API request</a> again, you should go back to the auth flow.' +
          '</td></tr></table>')


if __name__ == '__main__':
  # When running locally, disable OAuthlib's HTTPs verification.
  # ACTION ITEM for developers:
  #     When running in production *do not* leave this option enabled.
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  # Specify a hostname and port that are set as a valid redirect URI
  # for your API project in the Google API Console.
  app.run('localhost', 8080, debug=True)

Ruby

בדוגמה הזו נעשה שימוש במסגרת Sinatra.

require 'google/apis/drive_v2'
require 'google/api_client/client_secrets'
require 'json'
require 'sinatra'

enable :sessions
set :session_secret, 'setme'

get '/' do
  unless session.has_key?(:credentials)
    redirect to('/oauth2callback')
  end
  client_opts = JSON.parse(session[:credentials])
  auth_client = Signet::OAuth2::Client.new(client_opts)
  drive = Google::Apis::DriveV2::DriveService.new
  files = drive.list_files(options: { authorization: auth_client })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  client_secrets = Google::APIClient::ClientSecrets.load
  auth_client = client_secrets.to_authorization
  auth_client.update!(
    :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
    :redirect_uri => url('/oauth2callback'))
  if request['code'] == nil
    auth_uri = auth_client.authorization_uri.to_s
    redirect to(auth_uri)
  else
    auth_client.code = request['code']
    auth_client.fetch_access_token!
    auth_client.client_secret = nil
    session[:credentials] = auth_client.to_json
    redirect to('/')
  end
end

Node.js

כדי להציג דוגמה זו:

  1. ב- API Console, יש להוסיף את כתובת ה-URL של המכונה המקומית לרשימת כתובות ה-URL של ההפניה האוטומטית. לדוגמה, יש להוסיף http://localhost.
  2. עליך לוודא שהתקנת LTS, LTS פעיל או גרסה נוכחית של Node.js במערכת תחזוקה.
  3. יצירת ספרייה חדשה והחלפה אליה. למשל:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. Install the Google API Client Library for Node.js using npm:
    npm install googleapis
  5. יש ליצור את הקבצים main.js עם התוכן שלמטה.
  6. דוגמה:
    node .\main.js

primary.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
 * To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true
});

/* Global variable that stores user credential in this code example.
 * ACTION ITEM for developers:
 *   Store user's refresh token in your data store if
 *   incorporating this code into your real app.
 *   For more information on handling refresh tokens,
 *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
 */
let userCredential = null;

async function main() {
  const server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google's OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }

    // Receive the callback from Google's OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) { // An error response e.g. error=access_denied
        console.log('Error:' + q.error);
      } else { // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        oauth2Client.setCredentials(tokens);

        /** Save credential to the global variable in case access token was refreshed.
          * ACTION ITEM: In a production app, you likely want to save the refresh token
          *              in a secure persistent database instead. */
        userCredential = tokens;

        // Example of using Google Drive API to list filenames in user's Drive.
        const drive = google.drive('v3');
        drive.files.list({
          auth: oauth2Client,
          pageSize: 10,
          fields: 'nextPageToken, files(id, name)',
        }, (err1, res1) => {
          if (err1) return console.log('The API returned an error: ' + err1);
          const files = res1.data.files;
          if (files.length) {
            console.log('Files:');
            files.map((file) => {
              console.log(`${file.name} (${file.id})`);
            });
          } else {
            console.log('No files found.');
          }
        });
      }
    }

    // Example on revoking a token
    if (req.url == '/revoke') {
      // Build the string for the POST request
      let postData = "token=" + userCredential.access_token;

      // Options for POST request to Google's OAuth 2.0 server to revoke a token
      let postOptions = {
        host: 'oauth2.googleapis.com',
        port: '443',
        path: '/revoke',
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': Buffer.byteLength(postData)
        }
      };

      // Set up the request
      const postReq = https.request(postOptions, function (res) {
        res.setEncoding('utf8');
        res.on('data', d => {
          console.log('Response: ' + d);
        });
      });

      postReq.on('error', error => {
        console.log(error)
      });

      // Post the request with data
      postReq.write(postData);
      postReq.end();
    }
    res.end();
  }).listen(80);
}
main().catch(console.error);

HTTP/REST

בדוגמה הזו ב-Python נעשה שימוש במסגרת Flask ובספרייה Requests (בקשות) כדי להמחיש את תהליך OAuth 2.0 באינטרנט. בתהליך הזה מומלץ להשתמש בספריית הלקוחות של Google API עבור Python. (הדוגמה בכרטיסייה Python משתמשת בספריית הלקוח).

import json

import flask
import requests


app = flask.Flask(__name__)

CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly'
REDIRECT_URI = 'http://example.com/oauth2callback'


@app.route('/')
def index():
  if 'credentials' not in flask.session:
    return flask.redirect(flask.url_for('oauth2callback'))
  credentials = json.loads(flask.session['credentials'])
  if credentials['expires_in'] <= 0:
    return flask.redirect(flask.url_for('oauth2callback'))
  else:
    headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
    req_uri = 'https://www.googleapis.com/drive/v2/files'
    r = requests.get(req_uri, headers=headers)
    return r.text


@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE)
    return flask.redirect(auth_uri)
  else:
    auth_code = flask.request.args.get('code')
    data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}
    r = requests.post('https://oauth2.googleapis.com/token', data=data)
    flask.session['credentials'] = r.text
    return flask.redirect(flask.url_for('index'))


if __name__ == '__main__':
  import uuid
  app.secret_key = str(uuid.uuid4())
  app.debug = False
  app.run()

כללי אימות URI של הפניה אוטומטית

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

כללי אימות
סכמה

URI של הפניות אוטומטיות חייבים להשתמש בסכימת HTTPS ולא ב-HTTP רגיל. URI של Localhost (כולל URI של כתובת IP של מארח מקומי) פטורים מהכלל הזה.

מארח

המארחים לא יכולים להיות כתובות IP גולמיות. כתובות IP של מארחים מקומיים פטורות מהכלל הזה.

דומיין
  • הדומיינים ברמה העליונה (דומיינים ברמה העליונה) חייבים להשתייך לרשימת הסיומות הציבוריות.
  • דומיין המארח לא יכול להיות “googleusercontent.com”.
  • מזהי URI של הפניות אוטומטיות לא יכולים לכלול דומיינים של כתובות URL מקוצרות (למשל goo.gl), אלא אם הדומיין הוא בבעלות האפליקציה. בנוסף, אם אפליקציה שבבעלותה דומיין קצר יותר בוחרת לבצע הפניה אוטומטית לאותו דומיין, ה-URI של ההפניה האוטומטית חייב להכיל את “/google-callback/” בנתיב שלו או להסתיים ב- “/google-callback”.
  • פרטי משתמש

    מזהי URI של הפניה אוטומטית לא יכולים להכיל את רכיב המשנה userinfo.

    נתיב

    מזהי URI של הפניה אוטומטית לא יכולים להכיל מעבר נתיב (שנקרא גם 'מעקב אחורי' של הספרייה). המזהה הזה מיוצג על ידי “/..” או “\..”, או על ידי הקידוד שלהם של כתובות ה-URL.

    שאילתה

    מזהי URI של הפניה אוטומטית לא יכולים להכיל הפניות פתוחות.

    שבר

    מזהי URI של הפניה אוטומטית לא יכולים להכיל את רכיב המקטע.

    תווים מזהי URI של הפניה אוטומטית לא יכולים להכיל תווים מסוימים, כולל:
    • תווים כלליים לחיפוש ('*')
    • תווי ASCII שאינם ניתנים להדפסה
    • קידוד אחוזים לא חוקיים (כל קידוד אחוזים שאינו פועל בצורה של קידוד כתובת אתר של סימן אחוזים ואחריו שתי ספרות הקסדצימליות)
    • תווי null (תו NULL מקודד, למשל, %00, %C0%80

    הרשאה מצטברת

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

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

    במקרה הזה, בזמן הכניסה לחשבון, האפליקציה עשויה לבקש מההיקפים של openid ו profile לבצע כניסה בסיסית, ולאחר מכן לבקש את היקף https://www.googleapis.com/auth/drive.file במועד הבקשה הראשונה כדי לשמור מיקס.

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

    הכללים הבאים חלים על אסימון גישה שהתקבל מהרשאה מצטברת:

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

    דוגמאות הקוד הספציפיות לשפה בשלב 1: הגדרת פרמטרים של הרשאה וכתובת האתר להפניה אוטומטית לדוגמה מסוג HTTP/REST בשלב 2: הפניה אוטומטית לשרת OAuth 2.0 של Google משתמשות בהרשאה מצטברת. דוגמאות הקוד שמופיעות למטה גם מראות את הקוד שצריך להוסיף כדי להשתמש בהרשאה מצטברת.

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    ב-Python, מגדירים את הארגומנט include_granted_scopes של מילות המפתח כ-true כדי לוודא שבקשת הרשאה כוללת היקפים שהוענקו בעבר. ייתכן שהארגומנט include_granted_scopes לא יהיה הארגומנט היחיד של מילת המפתח שהגדרת, כפי שמוצג בדוגמה הבאה.

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Ruby

    auth_client.update!(
      :additional_parameters => {"include_granted_scopes" => "true"}
    )

    Node.js

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

    HTTP/REST

    GET https://accounts.google.com/o/oauth2/v2/auth?
      client_id=your_client_id&
      response_type=code&
      state=state_parameter_passthrough_value&
      scope=https%3A//www.googleapis.com/auth/drive.file&
      redirect_uri=https%3A//oauth2.example.com/code&
      prompt=consent&
      include_granted_scopes=true

    רענון אסימון גישה (גישה אופליין)

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

    • אם משתמשים בספריית לקוח של Google API, אובייקט הלקוח מרענן את אסימון הגישה לפי הצורך, כל עוד מגדירים את האובייקט לגישה במצב אופליין.
    • אם בחרת לא להשתמש בספריית לקוח, עליך להגדיר את פרמטר השאילתה access_type של HTTP ל-offline כאשר מתבצעת הפניה אוטומטית של המשתמש אל שרת OAuth 2.0 של Google. במקרה כזה, שרת ההרשאות של Google מחזיר אסימון רענון כאשר ממירים קוד הרשאה לאסימון גישה. לאחר מכן, אם תוקף אסימון הגישה פג (או בכל תאריך אחר), אפשר להשתמש באסימון רענון כדי לקבל אסימון גישה חדש.

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

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

    PHP

    אם לאפליקציה שלך נדרשת גישה אופליין ל-Google API, יש להגדיר את סוג הגישה של לקוח ה-API כ-offline:

    $client->setAccessType("offline");

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

    Python

    ב-Python, מגדירים את הארגומנט access_type של מילות המפתח ל-offline כדי להבטיח שניתן יהיה לרענן את אסימון הגישה בלי להציג מחדש את ההרשאה למשתמש. ייתכן שהארגומנט access_type לא יהיה הארגומנט היחיד של מילת המפתח שהגדרת, כפי שמוצג בדוגמה הבאה.

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

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

    Ruby

    אם לאפליקציה שלך נדרשת גישה אופליין ל-Google API, יש להגדיר את סוג הגישה של לקוח ה-API כ-offline:

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

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

    Node.js

    אם לאפליקציה שלך נדרשת גישה אופליין ל-Google API, יש להגדיר את סוג הגישה של לקוח ה-API כ-offline:

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

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

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

    oauth2Client.on('tokens', (tokens) => {
      if (tokens.refresh_token) {
        // store the refresh_token in your secure persistent database
        console.log(tokens.refresh_token);
      }
      console.log(tokens.access_token);
    });

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

    כדי להגדיר את refresh_token במועד מאוחר יותר, אפשר להשתמש בשיטה setCredentials:

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });
    

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

    HTTP/REST

    כדי לרענן אסימון גישה, האפליקציה שלך שולחת בקשת HTTPS של POST לשרת ההרשאות של Google (https://oauth2.googleapis.com/token) שכולל את הפרמטרים הבאים:

    שדות
    client_id מספר הלקוח שהתקבל מה- API Console.
    client_secret סוד הלקוח שהתקבל מה- API Console.
    grant_type כפי שמוגדר במפרט OAuth 2.0, יש להגדיר את הערך של השדה הזה כ-refresh_token.
    refresh_token אסימון הרענון הוחזר מהמרת קוד ההרשאות.

    בקטע הבא מוצגת בקשה לדוגמה:

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    
    client_id=your_client_id&
    client_secret=your_client_secret&
    refresh_token=refresh_token&
    grant_type=refresh_token

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

    {
      "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
      "expires_in": 3920,
      "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
      "token_type": "Bearer"
    }

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

    ביטול אסימון

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

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

    PHP

    כדי לבטל אסימון באופן פרוגרמטי, יש להתקשר אל revokeToken():

    $client->revokeToken();

    Python

    כדי לבטל אסימון באופן פרוגרמטי, יש לבקש מ-https://oauth2.googleapis.com/revoke לכלול את האסימון כפרמטר ולהגדיר את הכותרת Content-Type:

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    Ruby

    כדי לבטל אסימון באופן פרוגרמטי, יש להגיש בקשת HTTP בנקודת הקצה (oauth2.revoke):

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
    

    האסימון יכול להיות אסימון גישה או אסימון רענון. אם האסימון הוא אסימון גישה ויש לו אסימון רענון תואם, גם אסימון הרענון יבוטל.

    אם הביטול יבוטל, קוד הסטטוס של התגובה יהיה 200. במקרה של שגיאות, מוחזר קוד סטטוס 400 יחד עם קוד שגיאה.

    Node.js

    כדי לבטל אסימון באופן פרוגרמטי, יש להגיש בקשת HTTPS POST לנקודת קצה (endpoint) של /revoke:

    const https = require('https');
    
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;
    
    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });
    
    postReq.on('error', error => {
      console.log(error)
    });
    
    // Post the request with data
    postReq.write(postData);
    postReq.end();
    

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

    אם הביטול יבוטל, קוד הסטטוס של התגובה יהיה 200. במקרה של שגיאות, מוחזר קוד סטטוס 400 יחד עם קוד שגיאה.

    HTTP/REST

    כדי לבטל אסימון באופן פרוגרמטי, האפליקציה שולחת בקשה https://oauth2.googleapis.com/revoke וכוללת את האסימון כפרמטר:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    האסימון יכול להיות אסימון גישה או אסימון רענון. אם האסימון הוא אסימון גישה ויש לו אסימון רענון תואם, גם אסימון הרענון יבוטל.

    אם הביטול יסתיים בהצלחה, קוד סטטוס ה-HTTP של התגובה הוא 200. במקרה של שגיאות, מוחזר קוד סטטוס HTTP 400 יחד עם קוד שגיאה.