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

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

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

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

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

ספריות לקוח

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

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

ספריות לקוח של 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. לוחצים על Create credentials > מזהה הלקוח ב-OAuth.
  3. בוחרים בסוג האפליקציה Web application.
  4. ממלאים את הטופס ולוחצים על יצירה. אפליקציות שמשתמשות בשפות ובמסגרות כמו PHP, Java, Python, Ruby ו-NET .חייבים לציין מזהי URI מורשים להפניות אוטומטיות. מזהי URI להפניה אוטומטית הם נקודות הקצה שאליהן שרת OAuth 2.0 יכול לשלוח תגובות. האלה נקודות הקצה צריכות לפעול בהתאם לכללי האימות של Google.

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

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

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

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

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

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

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

המסמך היקפי API של OAuth 2.0 מכיל רשימת היקפים שבהם תוכלו להשתמש כדי לגשת ל-Google APIs.

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

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

PHP

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

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

    composer require google/apiclient:^2.10

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
  • ה-framework של אפליקציית האינטרנט של Flask Python.
    pip install --upgrade flask
  • ספריית ה-HTTP requests.
    pip install --upgrade requests

Ruby

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

  • Ruby 2.6 ומעלה
  • ספריית Google Auth ל-Ruby:

    gem install googleauth
  • מסגרת אפליקציית האינטרנט Sinatra Ruby.

    gem install sinatra

Node.js

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

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

    npm install googleapis crypto express express-session

HTTP/REST

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

קבלת אסימוני גישה מסוג 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 ותגדירו בכתובת האתר הזו.

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

PHP

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

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

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

$client = new Google\Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfig('client_secret.json');

// Required, to set the scope value, call the addScope function
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

// Required, call the setRedirectUri function to specify a valid redirect URI for the
// provided client_id
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');

// Recommended, 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');

// Recommended, call the setState function. Using a state value can increase your assurance that
// an incoming connection is the result of an authentication request.
$client->setState($sample_passthrough_value);

// Optional, if your application knows which user is trying to authenticate, it can use this
// parameter to provide a hint to the Google Authentication Server.
$client->setLoginHint('hint@example.com');

// Optional, call the setPrompt function to set "consent" will prompt the user for consent
$client->setPrompt('consent');

// Optional, call the setIncludeGrantedScopes function with true to enable incremental
// authorization
$client->setIncludeGrantedScopes(true);

Python

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

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

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

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Required, call the from_client_secrets_file method to retrieve the client ID from a
# client_secret.json file. The client ID (from that file) and access scopes are required. (You can
# also use the from_client_config method, which passes the client configuration as it originally
# appeared in a client secrets file but doesn't access the file itself.)
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

# Required, 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(
    # Recommended, 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',
    # Optional, enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true',
    # Optional, if your application knows which user is trying to authenticate, it can use this
    # parameter to provide a hint to the Google Authentication Server.
    login_hint='hint@example.com',
    # Optional, set prompt to 'consent' will prompt the user for consent
    prompt='consent')

Ruby

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

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

require 'google/apis/drive_v3'
require "googleauth"
require 'googleauth/stores/redis_token_store'

client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
scope = 'https://www.googleapis.com/auth/drive.metadata.readonly'
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')

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

Node.js

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

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

const {google} = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * 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 secure random state value.
const state = crypto.randomBytes(32).toString('hex');

// Store state in the session
req.session.state = state;

// 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,
  // Include the state parameter to reduce the risk of CSRF attacks.
  state: state
});

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

HTTP/REST

נקודת הקצה מסוג OAuth 2.0 של Google היא https://accounts.google.com/o/oauth2/v2/auth. הזה אפשר לגשת לנקודת הקצה (endpoint) רק באמצעות 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 יכול להגביר את ��ביטחון שחיבור נכנס הוא תוצאה של בקשת אימות. אם יוצרים מחרוזת אקראית או מקודדים גיבוב של קובץ cookie, ערך אחר שמתעד את המצב של הלקוח, אפשר לאמת את התגובה לוודא גם שהבקשה והתגובה הגיעו מאותו ��פדפן, אספקת הגנה מפני מתקפות כגון בקשה בין אתרים זיוף. לצפייה OpenID Connect תיעוד לדוגמה של יצירה ואישור של אסימון state.

include_granted_scopes אופציונלי

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

login_hint אופציונלי

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

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

prompt אופציונלי

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

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

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 להרשאה באמצעות אתר Flask מסגרת אפליקציה:

return flask.redirect(authorization_url)

Ruby

  1. יצירת כתובת URL כדי לבקש גישה משרת OAuth 2.0 של Google:
    auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
  2. מפנים את המשתמש לכתובת auth_uri.

Node.js

  1. משתמשים בכתובת ה-URL שנוצרה authorizationUrl משלב 1 שיטה generateAuthUrl לבקשת גישה משרת OAuth 2.0 של Google.
  2. מפנים את המשתמש לכתובת authorizationUrl.
    res.redirect(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 של Google עשויות להציג הודעות שגיאה למשתמשים במקום תהליכים של אימות והרשאה. קודי שגיאה נפוצים והצעות מפורטות בהמשך.

admin_policy_enforced

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

disallowed_useragent

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

Android

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

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

iOS

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

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

org_internal

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

invalid_client

סוד הלקוח ב-OAuth שגוי. כדאי לקרוא את לקוח OAuth , כולל מזהה הלקוח והסוד שמשמשים לבקשה הזו.

invalid_grant

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

redirect_uri_mismatch

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

הפרמטר redirect_uri עשוי להתייחס לתהליך של OAuth מחוץ למסגרת (OOB) שכולל הוצא משימוש ולא נתמך יותר. עיינו ב מדריך ההעברה כדי לעדכן את של Google Analytics.

invalid_request

יש בעיה בבקשה ששלחת. יכולות להיות לכך כמה סיבות:

  • פורמט הבקשה שגוי
  • בבקשה היו חסרי�� פרמטרים נדרשים
  • הבקשה משתמשת בשיטת הרשאה ש-Google לא תומכת בה. אימות OAuth משתמשת בשיטת שילוב מומלצת.

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

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

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

תגובת שגיאה:

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: קוד ההרשאה של Exchange לרענון וגישה אסימונים

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

PHP

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

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

אפשר לאחזר את אסימון הגישה באמצעות ה-method 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

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

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

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

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
app.get('/oauth2callback', async (req, res) => {
  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 if (q.state !== req.session.state) { //check state value
    console.log('State mismatch. Possible CSRF attack');
    res.end('State mismatch. Possible CSRF attack');
  } else { // 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 בבקשה הראשונית שרת ההרשאות.

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

שדות
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"
}

שגיאות

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

invalid_grant

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

קריאה ל-Google APIs

PHP

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

  1. אם צריך להחיל אסימון גישה על אובייקט Google\Client חדש – לדוגמה, אם אחסנתם את אסימון הגישה בסשן של משתמש — השתמשו setAccessToken method:
    $client->setAccessToken($access_token);
  2. יוצרים אובייקט שירות ל-API שאליו רוצים לקרוא. אתם יוצרים אובייקט שירות לפי שליחת אובייקט Google\Client מורשה ל-constructor של ה-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 שאליו רוצים לקרוא. אתם יוצרים אובייקט שירות לפי קריאה ל-method build של הספרייה googleapiclient.discovery באמצעות השם והגרסה של ה-API ושל פרטי הכניסה של המשתמש: לדוגמה, כדי להפעיל את גרסה 3 של Drive API:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. שולחים בקשות לשירות ה-API באמצעות הממשק שסופק על ידי אובייקט השירות. לדוגמה, כדי להציג רשימה של הקבצים ב-Google Drive של המשתמש המאומת:
    files = drive.files().list().execute()

Ruby

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

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

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

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

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 בשם נתון חשבון משתמש, אם היקפי הגישה הנדרשים על ידי ה-API הוענקו. כדי לעשות את זה, צריך לכלול אסימון הגישה בבקשה ל-API על ידי הכללת שאילתת access_token או ערך Bearer של כותרת HTTP בAuthorization. כשהדבר אפשרי, עדיף להשתמש בכותרת HTTP, כי מחרוזות השאילתה בדרך כלל גלויות ביומני השרת. במרבית במקרים מסוימים תוכלו להשתמש בספריית לקוח כדי להגדיר את הקריאות ל-Google APIs (לדוגמה, שליחת קריאה ל-Drive Files API).

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

דוגמאות ל-HTTP GET

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

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:
    composer require google/apiclient:^2.10
  4. יצירת הקבצים index.php ו-oauth2callback.php שמכילים את התוכן שלמטה.
  5. מריצים את הדוגמה באמצעות שרת אינטרנט שמוגדר להציג PHP. אם אתם משתמשים ב-PHP 5.6 ואילך, יכול להשתמש בשרת האינטרנט המובנה של PHP לבדיקה:
    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'])) {
  // Generate and set state value
  $state = bin2hex(random_bytes(16));
  $client->setState($state);
  $_SESSION['state'] = $state;

  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  // Check the state value
  if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
    die('State mismatch. Possible CSRF attack.');
  }
  $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

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

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

בדוגמה הזו נעשה שימוש ב-framework של Sinatra.

require 'google/apis/drive_v3'
require 'sinatra'
require 'googleauth'
require 'googleauth/stores/redis_token_store'

configure do
  enable :sessions

  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
  set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback')
end

get '/' do
  user_id = settings.client_id.id
  credentials = settings.authorizer.get_credentials(user_id, request)
  if credentials.nil?
    redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request)
  end
  drive = Google::Apis::DriveV3::DriveService.new
  files = drive.list_files(options: { authorization: credentials })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

כדי להריץ את הדוגמה הזו:

  1. בקטע API Console, צריך להוסיף את כתובת ה-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

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * 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'
];
/* 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 app = express();

  app.use(session({
    secret: 'your_secure_secret_key', // Replace with a strong secret
    resave: false,
    saveUninitialized: false,
  }));

  // Example on redirecting user to Google's OAuth 2.0 server.
  app.get('/', async (req, res) => {
    // Generate a secure random state value.
    const state = crypto.randomBytes(32).toString('hex');
    // Store state in the session
    req.session.state = state;

    // 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,
      // Include the state parameter to reduce the risk of CSRF attacks.
      state: state
    });

    res.redirect(authorizationUrl);
  });

  // Receive the callback from Google's OAuth 2.0 server.
  app.get('/oauth2callback', async (req, res) => {
    // 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 if (q.state !== req.session.state) { //check state value
      console.log('State mismatch. Possible CSRF attack');
      res.end('State mismatch. Possible CSRF attack');
    } 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
  app.get('/revoke', async (req, res) => {
    // 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();
  });


  const server = http.createServer(app);
  server.listen(80);
}
main().catch(console.error);

HTTP/REST

בדוגמה הזו ב-Python משתמשים ב-framework של Flask ובספרייה בקשות להדגים את פרוטוקול 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:
    state = str(uuid.uuid4())
    flask.session['state'] = state
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
                                                                          SCOPE, state)
    return flask.redirect(auth_uri)
  else:
    if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
      return 'State mismatch. Possible CSRF attack.', 400

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

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

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

מארח

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

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

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

    נתיב

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

    שאילתה

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

    מקטע

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

    דמויות מזהי URI של הפניות לא יכולים להכיל תווים מסוימים, כולל:
    • תווים כלליים לחיפוש ('*')
    • תווי ASCII שאינם ניתנים להדפסה
    • קידודים באחוזים לא חוקיים (כל אחוז קידוד שלא תואם לקידוד כתובות URL סימן אחוז ואחריו שתי ספרות הקסדצימליות
    • תווי 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, אובייקט הלקוח עובר רענון את אסימון הגישה לפי הצורך, כל עוד מגדירים את האובייקט לגישה אופליין.
    • אם לא משתמשים בספריית לקוח, צריך להגדיר את ה-HTTP access_type של השאילתה ל-offline כאשר מתבצעת הפניה אוטומטית של המשתמש אל שרת OAuth 2.0 של Google. במקרה כזה, שרת ההרשאות של Google מחזיר אסימון רענון בעת החלפת הרשאה code לאסימון גישה. לאחר מכן, אם התוקף של אסימון הגישה יפוג (או בכל זמן אחר), יכול להשתמש באסימון רענון כדי לקבל אסימון גישה חדש.

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

    כדי לרענן אסימון גישה, האפליקציה שולחת כתובת URL מסוג 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"
    }

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

    ביטול אסימון

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

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

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

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

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

    Node.js

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

    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 עם קוד שגיאה.