במסמך הזה מוסבר איך אפליקציות של שרת אינטרנט משתמשות בספריות לקוח של Google API או בנקודות קצה של OAuth 2.0 של Google כדי להטמיע הרשאת OAuth 2.0 כדי לגשת ל-Google APIs.
פרוטוקול 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 נכונות להפניה אוטומטית, ועוזרת להטמיע רכיבי handler של הפניות אוטומטיות שמחליפים קודי הרשאה באסימוני גישה.
ספריות הלקוח של Google API לאפליקציות בצד השרת זמינות בשפות הבאות:
דרישות מוקדמות
הפעלת ממשקי API בפרויקט
כל אפליקציה שקוראת ל-Google APIs צריכה להפעיל את ממשקי ה-API האלה ב- API Console.
כדי להפעיל API בפרויקט:
- Open the API Library ב Google API Console.
- If prompted, select a project, or create a new one.
- בטבלה API Library מפורטים כל ממשקי ה-API הזמינים, בקיבוץ לפי משפחת מוצרים ופופולריות. אם ממשק ה-API שרוצים להפעיל לא מופיע ברשימה, משתמשים בחיפוש כדי למצוא אותו או לוחצים על הצגת הכול במשפחת המוצרים שאליה הוא שייך.
- בוחרים את ממשק ה-API שרוצים להפעיל ולוחצים על הלחצן Enable (הפעלה).
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
יצירת פרטי כניסה להרשאה
לכל אפליקציה שמשתמשת ב-OAuth 2.0 כדי לגשת אל Google APIs, צריכות להיות פרטי כניסה להרשאה שמזהים את האפליקציה לשרת OAuth 2.0 של Google. בשלבים הבאים נסביר איך ליצור פרטי כניסה לפרויקט. לאחר מכן האפליקציות שלך יוכלו להשתמש בפרטי הכניסה כדי לגשת לממשקי API שהפעלת בפרויקט הזה.
- Go to the Credentials page.
- לוחצים על יצירת פרטי כניסה > מזהה לקוח OAuth.
- בוחרים את סוג האפליקציה Web application.
- ממלאים את הטופס ולוחצים על יצירה. באפליקציות שמשתמשות בשפות ובמסגרות
כמו 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.
-
לקוח Google APIs Node.js:
npm install googleapis crypto express express-session
HTTP/REST
אין צורך להתקין ספריות כדי לקרוא ישירות לנקודות הקצה של OAuth 2.0.
קבלת אסימוני גישה מסוג OAuth 2.0
בשלבים הבאים מוצג האופן שבו האפליקציה שלך יוצרת אינטראקציה עם שרת OAuth 2.0 של Google כדי לקבל את הסכמת המשתמש לבצע בקשה ל-API בשם המשתמש. האפליקציה שלך חייבת לקבל את ההסכמה הזו כדי שניתן יהיה להריץ בקשת Google API שמחייבת הרשאת משתמש.
הרשימה שלמטה מסכמת בקצרה את השלבים האלה:
- האפליקציה שלך מזהה את ההרשאות הנחוצות לה.
- האפליקציה מפנה את המשתמשים ל-Google עם רשימת ההרשאות הנדרשות.
- המשתמש מחליט אם להעניק את ההרשאות לאפליקציה שלכם.
- האפליקציה שלך חושפת את מה שהמשתמש החליט.
- אם המשתמש נתן את ההרשאות הנדרשות, האפליקציה מאחזרת את האסימונים שנדרשים כדי לשלוח בקשות 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(); // 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 של נקודת הקצה לאימות של האפליקציה, שתטפל בתגובה משרת 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 של נקודת הקצה לאימות של האפליקציה, שתטפל בתגובה משרת 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
נקודת הקצה (endpoint) OAuth 2.0 של Google נמצאת בכתובת https://accounts.google.com/o/oauth2/v2/auth
. אפשר לגשת לנקודת הקצה הזו רק ב-HTTPS. המערכת דוחה חיבורי HTTP פשוטים.
שרת ההרשאות של Google תומך בפרמטרים הבאים של מחרוזת השאילתה לאפליקציות של שרת האינטרנט:
פרמטרים | |||||||
---|---|---|---|---|---|---|---|
client_id |
חובה
מזהה הלקוח באפליקציה שלכם. הערך הזה מופיע ב Credentials page API Console. |
||||||
redirect_uri |
חובה
המדיניות הזו קובעת לאן שרת ה-API יפנה את המשתמש אחרי שהוא ישלים את
תהליך ההרשאה. הערך צריך להתאים במדויק לאחד ממזהי ה-URI המורשים להפניה אוטומטית בלקוח OAuth 2.0, שהגדרת ב- API Console
Credentials pageשל הלקוח. אם הערך הזה לא תואם
ל-URI מורשה להפניה אוטומטית עבור ה- הערה: הסכמה |
||||||
response_type |
חובה
המדיניות הזו קובעת אם נקודת הקצה (endpoint) של Google OAuth 2.0 תחזיר קוד הרשאה. צריך להגדיר את ערך הפרמטר ל- |
||||||
scope |
חובה
רשימה של היקפי הרשאות שמופרדים ברווחים שמציינים את המשאבים שהאפליקציה שלכם יכולה לגשת אליהם בשם המשתמש. הערכים האלה מציינים את מסך ההסכמה ש-Google מציגה למשתמש. היקפי ההרשאות מאפשרים לאפליקציה לבקש גישה רק למשאבים שנחוצים לה, וגם מאפשרים למשתמשים לשלוט בנפח הגישה שהם מעניקים לאפליקציה. לכן יש קשר הפוך בין מספר ההיקפים המבוקשים לבין הסבירות לקבל הסכמה מהמשתמשים. כשזה אפשרי, מומלץ שהאפליקציה תבקש גישה להיקפי הרשאות בהקשר המתאים. בקשת גישה לנתוני משתמש בהקשר המתאים באמצעות הרשאה מצטברת עוזרת למשתמשים להבין בקלות למה האפליקציה צריכה את הגישה שהיא מבקשת. |
||||||
access_type |
המלצות
האפשרות מציינת אם האפליקציה יכולה לרענן אסימוני גישה כשהמשתמש לא נוכח בדפדפן. ערכי הפרמטרים החוקיים הם אם האפליקציה צריכה לרענן את אסימוני הגישה כשהמשתמש לא נמצא בדפדפן, אפשר להגדיר את הערך כ- |
||||||
state |
המלצות
מציינת כל ערך מחרוזת שהאפליקציה משתמשת בו כדי לשמור על המצב בין בקשת ההרשאה לבין התגובה של שרת ההרשאות.
השרת מחזיר את הערך המדויק ששולחים בתור צמד אפשר להשתמש בפרמטר הזה לכמה מטרות, כמו הפניית המשתמש
למשאב הנכון באפליקציה, שליחת נתונים חד-פעמיים (nonces) וצמצום זיוף בקשות בין אתרים. מאחר שניתן לנחש את |
||||||
include_granted_scopes |
אופציונלי
מאפשרת לאפליקציות להשתמש בהרשאה מצטברת כדי לבקש גישה להיקפים נוספים בהקשר. אם מגדירים את הערך של הפרמטר הזה ל- |
||||||
enable_granular_consent |
אופציונלי
ברירת המחדל היא כש-Google מפעילה הרשאות מפורטות לאפליקציה, לפרמטר הזה לא תהיה יותר השפעה. |
||||||
login_hint |
אופציונלי
אם האפליקציה שלכם יודעת איזה משתמש מנסה לבצע אימות, היא יכולה להשתמש בפרמטר הזה כדי לספק רמז לשרת האימות של Google. השרת משתמש ברמז כדי לפשט את תהליך ההתחברות על ידי מילוי מראש של שדה האימייל בטופס הכניסה או בחירה בסשן המתאים עם כניסות מרובות. צריך להגדיר את ערך הפרמטר לכתובת אימייל או למזהה |
||||||
prompt |
אופציונלי
רשימה של הנחיות להצגת המשתמש, שמופרדת ברווחים ותלויות אותיות רישיות. אם לא מציינים את הפרמטר הזה, תוצג למשתמש בקשה רק בפעם הראשונה שהפרויקט יבקש גישה. מידע נוסף זמין במאמר הצגת בקשה להסכמה מחדש. הערכים האפשריים הם:
|
שלב 2: הפניה אוטומטית לשרת OAuth 2.0 של Google
צריך להפנות את המשתמש לשרת OAuth 2.0 של Google כדי להתחיל את תהליך האימות וההרשאה. בדרך כלל זה קורה כשהאפליקציה צריכה לגשת לנתוני המשתמש בפעם הראשונה. במקרה של הרשאה מצטברת, השלב הזה מתרחש גם כשהאפליקציה צריכה לגשת בפעם הראשונה למשאבים נוספים שעדיין אין לה הרשאת גישה אליה.
PHP
- יוצרים כתובת URL כדי לבקש גישה משרת OAuth 2.0 של Google:
$auth_url = $client->createAuthUrl();
- הפניית המשתמש אל
$auth_url
:header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Python
בדוגמה הזו אפשר לראות איך להפנות את המשתמש לכתובת ה-URL להרשאה באמצעות framework של אפליקציית האינטרנט של Flask:
return flask.redirect(authorization_url)
Ruby
- יוצרים כתובת URL כדי לבקש גישה משרת OAuth 2.0 של Google:
auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
- עליך להפנות את המשתמש אל
auth_uri
.
Node.js
-
משתמשים בכתובת ה-URL שנוצרה
authorizationUrl
משיטת שלב 1generateAuthUrl
כדי לבקש גישה משרת OAuth 2.0 של Google. -
עליך להפנות את המשתמש אל
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
נקודת הקצה של ההרשאה מוצגת בסוכן משתמש מוטמע שאסור לפי מדיניות OAuth 2.0 של Google.
Android
מפתחי Android עשויים להיתקל בהודעת השגיאה הזו כשהם פותחים בקשות הרשאה ב-android.webkit.WebView
.
במקום זאת, מפתחים צריכים להשתמש בספריות ל-Android, כמו
כניסה באמצעות חשבון Google ל-Android או AppAuth ל-Android של OpenID Foundation.
מפתחי אתרים עשויים להיתקל בשגיאה הזו כשאפליקציה ל-Android פותחת קישור כללי לאינטרנט בסוכן משתמש מוטמע, ומשתמש עובר לנקודת הקצה של הרשאת OAuth 2.0 של Google מהאתר שלך. המפתחים צריכים לאפשר לקישורים כלליים להיפתח ב-handler שמוגדר כברירת מחדל לקישורים של מערכת ההפעלה, שכולל גם את ה-handlers של קישורים לאפליקציות ל-Android או את אפליקציית הדפדפן שמוגדרת כברירת מחדל. גם ספריית הכרטיסיות בהתאמה אישית ב-Android נתמכת.
iOS
מפתחים של iOS ו-macOS עשויים להיתקל בשגיאה הזו כשפותחים בקשות הרשאה ב-WKWebView
.
במקום זאת, מפתחים צריכים להשתמש בספריות ל-iOS, כמו כניסה באמצעות חשבון Google ל-iOS או AppAuth ל-iOS של OpenID Foundation.
מפתחי אתרים עשויים להיתקל בשגיאה הזו כשאפליקציה ל-iOS או ל-macOS פותחת קישור כללי לאינטרנט בסוכן משתמש מוטמע, ומשתמש עובר לנקודת הקצה של הרשאת OAuth 2.0 של Google מהאתר שלכם. המפתחים צריכים לאפשר לקישורים כלליים להיפתח ב-handler שמוגדר כברירת מחדל לקישורים של
מערכת ההפעלה, שכולל גם את ה-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) שהוצאה משימוש וכבר לא נתמכת. כדי לעדכן את השילוב, אפשר לעיין
במדריך להעברת נתונים (מיגרציה).
invalid_request
משהו השתבש בבקשה ששלחת. יכולות להיות לכך כמה סיבות:
- פורמט הבקשה שגוי
- בבקשה היו חסרים פרמטרים נדרשים
- הבקשה משתמשת בשיטת הרשאה שאינה נתמכת על ידי Google. איך לוודא ששילוב ה-OAuth משתמש בשיטת שילוב מומלצת
שלב 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
בדף ההתקשרות חזרה, משתמשים בספרייה googleauth
כדי לאמת את התגובה של שרת ההרשאות. צריך להשתמש בשיטה authorizer.handle_auth_callback_deferred
כדי לשמור את קוד ההרשאה ולהפנות מחדש לכתובת ה-URL שביקשה את ההרשאה במקור. הפעולה הזו
דוחה את חילופי הקוד על ידי שמירה זמנית של התוצאות בסשן של המשתמש.
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url
Node.js
כדי להחליף קוד הרשאה באסימון גישה, משתמשים בשיטה getToken
:
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
בבקשה הראשונית הנשלחת לשרת ההרשאות של 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" }
שגיאות
כשמחליפים את קוד ההרשאה באסימון גישה, יכול להיות שתקבלו את השגיאה הבאה במקום התגובה הצפויה. קודי שגיאה נפוצים והצעות לפתרונות מפורטים בהמשך.
invalid_grant
קוד ההרשאה שסופק אינו חוקי או שהוא בפורמט שגוי. מבקשים קוד חדש על ידי הפעלה מחדש של תהליך OAuth, כדי לבקש מהמשתמש שוב הסכמה.
קריאה ל-Google APIs
PHP
כך משתמשים באסימון הגישה כדי לקרוא ל-Google APIs:
- אם צריך להחיל אסימון גישה על אובייקט
Google\Client
חדש – לדוגמה, אם אחסנתם את אסימון הגישה בסשן של משתמש – משתמשים בשיטהsetAccessToken
:$client->setAccessToken($access_token);
- יוצרים אובייקט שירות ל-API שרוצים לקרוא לו. כדי ליצור אובייקט שירות, מספקים ל-builder אובייקט
Google\Client
מורשה של ה-API שרוצים לקרוא לו. לדוגמה, כדי להפעיל את Drive API:$drive = new Google\Service\Drive($client);
- שולחים בקשות לשירות ה-API באמצעות הממשק שסופק על ידי אובייקט השירות.
לדוגמה, כדי להציג רשימה של הקבצים ב-Google Drive של המשתמש המאומת:
$files = $drive->files->listFiles(array())->getItems();
Python
אחרי קבלת אסימון גישה, האפליקציה שלך יכולה להשתמש באסימון הזה כדי לאשר בקשות API עבור חשבון משתמש נתון או חשבון שירות נתון. משתמשים בפרטי הכניסה הספציפיים למשתמש כדי ליצור אובייקט שירות ל-API שרוצים לקרוא, ואז משתמשים באובייקט הזה כדי לבצע בקשות מורשות של API.
- יוצרים אובייקט שירות ל-API שרוצים לקרוא לו. כדי ליצור אובייקט שירות, מפעילים את השיטה
build
של ספרייתgoogleapiclient.discovery
עם השם והגרסה של ה-API ועם פרטי הכניסה של המשתמש: לדוגמה, כדי להפעיל את גרסה 3 של Drive API:from googleapiclient.discovery import build drive = build('drive', 'v2', credentials=credentials)
- שולחים בקשות לשירות ה-API באמצעות הממשק שסופק על ידי אובייקט השירות.
לדוגמה, כדי להציג רשימה של הקבצים ב-Google Drive של המשתמש המאומת:
files = drive.files().list().execute()
Ruby
אחרי שמקבלים אסימון גישה, האפליקציה יכולה להשתמש באסימון הזה כדי לשלוח בקשות API בשם חשבון משתמש או חשבון שירות מסוימים. משתמשים בפרטי הכניסה הספציפיים למשתמש כדי ליצור אובייקט שירות ל-API שרוצים לקרוא, ואז משתמשים באובייקט הזה כדי לבצע בקשות מורשות של API.
- יוצרים אובייקט שירות ל-API שרוצים לקרוא לו.
לדוגמה, כדי להפעיל את גרסה 3 של Drive API:
drive = Google::Apis::DriveV3::DriveService.new
- מגדירים את פרטי הכניסה לשירות:
drive.authorization = credentials
- שולחים בקשות לשירות ה-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
אחרי שהאפליקציה תקבל אסימון גישה, תהיה לך אפשרות להשתמש באסימון כדי לבצע קריאות ל-Google API מטעם חשבון משתמש מסוים, אם היקפי הגישה הנדרשים ל-API ניתנו. כדי לעשות זאת, צריך לכלול
את אסימון הגישה בבקשה אל ה-API באמצעות פרמטר שאילתה access_token
או ערך Authorization
של כותרת HTTP Bearer
. כשאפשר, עדיף להשתמש בכותרת ה-HTTP, כי מחרוזות השאילתה מופיעות בדרך כלל ביומני השרת. ברוב המקרים,
אפשר להשתמש בספריית לקוח כדי להגדיר את הקריאות ל-Google APIs (לדוגמה,
בקריאה ל-Drive Files API).
אפשר לנסות את כל ממשקי ה-API של Google ולראות את ההיקף שלהם ב-OAuth 2.0 Playground.
דוגמאות GET של HTTP
קריאה לנקודת הקצה
drive.files
(ה-API של Drive Files) באמצעות כותרת ה-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
כדי להפעיל את הדוגמה הזו:
- בשדה API Console, מוסיפים את כתובת ה-URL של המכונה המקומית לרשימת כתובות ה-URL להפניה אוטומטית. לדוגמה, מוסיפים את
http://localhost:8080
. - יוצרים ספרייה חדשה ומשנים אותה אליה. לדוגמה:
mkdir ~/php-oauth2-example cd ~/php-oauth2-example
- מתקינים את ספריית הלקוח של Google API עבור PHP באמצעות Composer:
composer require google/apiclient:^2.10
- יוצרים את הקבצים
index.php
ו-oauth2callback.php
עם התוכן שלמטה. - מריצים את הדוגמה עם שרת אינטרנט שמוגדר לשרת 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
בדוגמה הזו נשתמש במסגרת Flask. היא
מפעילה אפליקציית אינטרנט ב-http://localhost:8080
שמאפשרת לבדוק את תהליך
OAuth 2.0. כשעוברים לכתובת ה-URL הזו, מוצגים ארבעה קישורים:
- בדיקה של בקשת 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
בדוגמה הזו נשתמש במסגרת 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
כדי להפעיל את הדוגמה הזו:
-
בשדה API Console, מוסיפים את כתובת ה-URL של המכונה המקומית לרשימת כתובות ה-URL להפניה אוטומטית. לדוגמה, מוסיפים את
http://localhost
. - חשוב לוודא שמותקנת אצלכם גרסת LTS לתחזוקה, גרסת LTS פעילה או הגרסה הנוכחית של Node.js מותקנת.
-
יוצרים ספרייה חדשה ומשנים אותה אליה. לדוגמה:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Install the
Google API Client
Library
for Node.js using npm:
npm install googleapis
-
יוצרים את הקבצים
main.js
עם התוכן שלמטה. -
מריצים את הדוגמה:
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 משתמשת במסגרת 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: 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 מחילה את כללי האימות הבאים על הפניה אוטומטית של URIs כדי לעזור למפתחים לשמור על אבטחת האפליקציות שלהם. מזהי ה-URI של ההפניה האוטומטית חייבים לעמוד בכללים האלה. בקטע RFC 3986 סעיף 3 אפשר למצוא מידע על ההגדרות של הדומיין, המארח, הנתיב, השאילתה, הסכימה ופרטי המשתמש, כפי שמתואר בהמשך.
כללי אימות | |
---|---|
סכמה |
מזהי URI של הפניות אוטומטיות חייבים להשתמש בסכמת HTTPS, ולא ב-HTTP פשוט. מזהי URI של מארחים מקומיים (כולל מזהי URI של כתובות IP של מארחים מקומיים) פטורים מהכלל הזה. |
מארח |
המארחים לא יכולים להיות כתובות IP גולמיות. כתובות IP של מארחים מקומיים לא פטורות מהכלל הזה. |
דומיין |
“googleusercontent.com” .goo.gl ), אלא אם הדומיין נמצא בבעלות האפליקציה. בנוסף, אם אפליקציה שבבעלותה דומיין מקצר בוחרת להפנות אוטומטית לדומיין הזה, ה-URI של ההפניה האוטומטית חייב לכלול את
“/google-callback/” בנתיב שלה או להסתיים ב-
“/google-callback” . |
פרטי משתמשים |
מזהי URI של הפניות אוטומטיות לא יכולים להכיל את רכיב המשנה של פרטי המשתמש. |
נתיב |
מזהי URI של הפניות אוטומטיות לא יכולים להכיל מעבר נתיב (נקרא גם מעקב אחר ספריות),
שמיוצג על ידי |
שאילתה |
מזהי URI של הפניות אוטומטיות לא יכולים להכיל הפניות אוטומטיות פתוחות. |
קטע |
מזהי URI להפניה אוטומטית לא יכולים להכיל את רכיב המקטע. |
תווים |
כתובות URI של הפניות אוטומטיות לא יכולות להכיל תווים מסוימים, כולל:
|
הרשאה מצטברת
בפרוטוקול OAuth 2.0, האפליקציה מבקשת הרשאה לגשת למשאבים שמזוהים באמצעות היקפי הרשאות. מומלץ לבקש הרשאה למשאבים בזמן הנכון – מומלץ בחוויית המשתמש. כדי להפעיל את השיטה הזו, שרת ההרשאות של Google תומך בהרשאות מצטברות. התכונה הזו מאפשרת לבקש היקפים לפי הצורך, ואם המשתמש מעניק הרשאה להיקף החדש, הוא מחזיר קוד הרשאה שאותו אפשר להחליף באסימון שמכיל את כל ההיקפים שהמשתמש העניק לפרויקט.
לדוגמה, אפליקציה שמאפשרת לאנשים לדגום טראקים של מוזיקה וליצור מיקסים עשויה להזדקק למעט מאוד משאבים בזמן הכניסה לחשבון, ולא רק בשם האדם שנכנס לחשבון. עם זאת, שמירת שילוב שהושלם תדרוש גישה ל-Google Drive שלהם. לרוב האנשים היו עושים זאת באופן טבעי אם הם ביקשו גישה ל-Google Drive שלהם רק בזמן שהאפליקציה הייתה צריכה אותה.
במקרה כזה, בזמן הכניסה האפליקציה עשויה לבקש מההיקפים openid
ו-profile
לבצע כניסה בסיסית, ולאחר מכן לבקש את ההיקף https://www.googleapis.com/auth/drive.file
בזמן הבקשה הראשונה כדי לשמור שילוב.
כדי להטמיע הרשאה מצטברת, צריך להשלים את התהליך הרגיל לבקשת אסימון גישה, אבל לוודא שבקשת ההרשאה כוללת היקפים שניתנו בעבר. כך האפליקציה לא צריכה לנהל כמה אסימוני גישה.
הכללים הבאים חלים על אסימון גישה שהתקבל מהרשאה מצטברת:
- ניתן להשתמש באסימון כדי לגשת למשאבים שתואמים לכל אחד מהיקפי ההרשאות שהוכנסו בהרשאה המשולבת החדשה.
- כשמשתמשים באסימון הרענון בהרשאה המשולבת כדי לקבל אסימון גישה, אסימון הגישה מייצג את ההרשאה המשולבת ואפשר להשתמש בו לכל אחד מערכי
scope
שכלולים בתגובה. - ההרשאה המשולבת כוללת את כל היקפי ההרשאות שהמשתמש העניק לפרויקט ה-API, גם אם התבקשו הרשאות מלקוחות שונים. לדוגמה, אם משתמש העניק גישה להיקף הרשאות אחד באמצעות לקוח למחשב של אפליקציה, ולאחר מכן העניק היקף אחר לאותה אפליקציה דרך לקוח לנייד, ההרשאה המשולבת תכלול את שני ההיקפים.
- אם מבטלים אסימון שמייצג הרשאה משולבת, תבוטל בו-זמנית הגישה לכל ההיקפים של ההרשאה הזו בשם המשתמש המשויך.
דוגמאות הקוד הספציפיות לשפה בשלב 1: הגדרת הפרמטרים של ההרשאות, ובדוגמה לכתובת ה-URL להפניה אוטומטית מסוג 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 מחזיר אסימון רענון כשמחליפים קוד הרשאה באסימון גישה. לאחר מכן, אם התוקף של אסימון הגישה יפוג (או בכל זמן אחר), תהיה לך אפשרות להשתמש באסימון רענון כדי לקבל אסימון גישה חדש.
בקשה לגישה אופליין היא דרישה לכל אפליקציה שצריכה לגשת ל-Google 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
כדי לרענן אסימון גישה, האפליקציה שלך שולחת בקשת POST
מסוג HTTPS לשרת ההרשאות של 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 לנקודת הקצה של /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
יחד עם קוד שגיאה.