במסמך הזה מוסבר איך אפליקציות של שרתי אינטרנט משתמשות בספריות לקוח של 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 שרוצים להפעיל ולוחצים על הלחצן הפעלה.
- 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.
- לוחצים על Create credentials > OAuth client ID.
- בוחרים את סוג האפליקציה Web application.
- ממלאים את הטופס ולוחצים על יצירה. באפליקציות שמשתמשות בשפות ובמסגרות כמו PHP, Java, Python, Ruby ו-NET., חובה לציין URIs מורשים להפניה אוטומטית. מזהי ה-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
- תוכנת האינטרנט של Flask Python.
pip install --upgrade flask
- ספריית ה-HTTP של
requests
.pip install --upgrade requests
Ruby
כדי להריץ את דוגמאות הקוד של Ruby במסמך הזה, צריך:
- Ruby 2.6 ומעלה
-
ספריית Google Auth עבור Ruby:
gem install googleauth
-
תוכנת האינטרנט של Synatra Ruby.
gem install sinatra
Node.js
כדי להריץ את דוגמאות הקוד של Node.js במסמך הזה, צריך:
- LTS התחזוקה, ה-LTS הפעיל או הגרסה הנוכחית של Node.js.
-
לקוח Google APIs Node.js:
npm install googleapis
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(); $client->setAuthConfig('client_secret.json'); $client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY); $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType('offline'); // Using "consent" will prompt the user for consent $client->setPrompt('consent'); $client->setIncludeGrantedScopes(true); // incremental auth
בבקשה מפורטים הפרטים הבאים:
פרמטרים | |||||||
---|---|---|---|---|---|---|---|
client_id |
נדרש
מזהה הלקוח של האפליקציה. אפשר למצוא את הערך הזה בשדה API Console Credentials page. ב-PHP, קוראים לפונקציה $client = new Google\Client(); $client->setAuthConfig('client_secret.json'); |
||||||
redirect_uri |
נדרש
המדיניות הזו קובעת לאן שרת ה-API יפנה את המשתמש אוטומטית אחרי שהמשתמש ישלים את תהליך ההרשאה. הערך צריך להיות זהה לאחד ממזהי ה-URI המורשים להפניה אוטומטית בלקוח OAuth 2.0 שהגדרת ב- API Console
Credentials pageשל הלקוח. אם הערך הזה לא תואם
ל-URI מורשה להפניה אוטומטית עבור חשוב לשים לב שהסכמה כדי להגדיר את הערך הזה ב-PHP, צריך להפעיל את הפונקציה $client->setRedirectUri('https://oauth2.example.com/code'); |
||||||
scope |
נדרש
רשימת היקפים מופרדת ברווחים של המשאבים שמציינים את המשאבים שהאפליקציה יכולה לגשת אליהם בשם המשתמש. הערכים האלה מציינים את מסך ההסכמה ש-Google מציגה למשתמש. היקפי הרשאות מאפשרים לאפליקציה לבקש גישה רק למשאבים הנדרשים, וגם מאפשרים למשתמשים לשלוט ברמת הגישה שהם מעניקים לאפליקציה. לכן, יש קשר הפוך בין מספר ההיקפים המבוקשים לבין הסבירות לקבלת הסכמת המשתמש. כדי להגדיר את הערך הזה ב-PHP, צריך להפעיל את הפונקציה $client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY); כשהדבר אפשרי, מומלץ שהאפליקציה תבקש גישה להיקפי הרשאות לפי הקשר. בקשת גישה לנתוני משתמשים בהקשר מסוים, באמצעות הרשאה מצטברת, תעזור למשתמשים להבין בקלות למה האפליקציה צריכה את הגישה שהיא מבקשת. |
||||||
access_type |
מומלץ
השדה הזה מציין אם האפליקציה יכולה לרענן את אסימוני הגישה כשהמשתמש לא נוכח בדפדפן. ערכי הפרמטרים החוקיים הם אם האפליקציה צריכה לרענן את אסימוני הגישה כשהמשתמש לא נוכח בדפדפן, צריך להגדיר את הערך כ- כדי להגדיר את הערך הזה ב-PHP, צריך להפעיל את הפונקציה $client->setAccessType('offline'); |
||||||
state |
מומלץ
מציינת את כל ערך המחרוזת שבו האפליקציה משתמשת כדי לשמור על המצב בין בקשת ההרשאה לבין התגובה של שרת ההרשאות.
השרת מחזיר את הערך המדויק ששלחת כצמד אפשר להשתמש בפרמטר הזה לכמה מטרות, כמו להפנות את המשתמש
למשאב הנכון באפליקציה, שליחת נתונים חד-פעמיים (nonces) וצמצום זיוף בקשות בין אתרים. מכיוון שאפשר לנחש את כדי להגדיר את הערך הזה ב-PHP, צריך להפעיל את הפונקציה $client->setState($sample_passthrough_value); |
||||||
include_granted_scopes |
אופציונלי
מאפשרת לאפליקציות להשתמש בהרשאה מצטברת כדי לבקש גישה להיקפים נוספים בהקשר. אם מגדירים לפרמטר הזה את הערך כדי להגדיר את הערך הזה ב-PHP, צריך להפעיל את הפונקציה $client->setIncludeGrantedScopes(true); |
||||||
enable_granular_consent |
אופציונלי
ברירת המחדל היא |
||||||
login_hint |
אופציונלי
אם האפליקציה יודעת איזה משתמש מנסה לבצע אימות, היא יכולה להשתמש בפרמטר הזה כדי לספק רמז לשרת האימות של Google. השרת משתמש ברמז כדי לפשט את תהליך ההתחברות, על ידי מילוי מראש של שדה האימייל בטופס הכניסה או על ידי בחירה בסשן המתאים של התחברות עם מספר חשבונות. מגדירים את ערך הפרמטר לכתובת אימייל או למזהה כדי להגדיר את הערך הזה ב-PHP, צריך להפעיל את הפונקציה $client->setLoginHint('None'); |
||||||
prompt |
אופציונלי
רשימת בקשות להצגת המשתמש מופרדת ברווחים ותלויות אותיות רישיות (case-sensitive). אם לא מציינים את הפרמטר הזה, המשתמש יקבל הודעה רק בפעם הראשונה שהפרויקט יבקש גישה. מידע נוסף זמין בקטע הצגת בקשה להסכמה מחדש. כדי להגדיר את הערך הזה ב-PHP, צריך להפעיל את הפונקציה $client->setPrompt('consent'); הערכים האפשריים הם:
|
Python
קטע הקוד הבא משתמש במודול google-auth-oauthlib.flow
כדי לבנות את בקשת ההרשאה.
הקוד בונה אובייקט Flow
, שמזהה את האפליקציה באמצעות מידע מהקובץ client_secret.json שהורדתם אחרי יצירת פרטי כניסה להרשאה. האובייקט הזה מזהה גם את היקפי ההרשאות שהאפליקציה מבקשת הרשאת גישה אליהם, ואת כתובת ה-URL של נקודת הקצה לאימות של האפליקציה, שיטפלו בתגובה משרת OAuth 2.0 של Google. לבסוף, הקוד מגדיר את הפרמטרים האופציונליים access_type
ו-include_granted_scopes
.
לדוגמה, הקוד הזה מבקש גישה לקריאה בלבד, במצב אופליין, ל-Google Drive של המשתמש:
import google.oauth2.credentials import google_auth_oauthlib.flow # Use the client_secret.json file to identify the application requesting # authorization. The client ID (from that file) and access scopes are required. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly']) # Indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. flow.redirect_uri = 'https://www.example.com/oauth2callback' # Generate URL for request to Google's OAuth 2.0 server. # Use kwargs to set optional request parameters. authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
בבקשה מפורטים הפרטים הבאים:
פרמטרים | |||||||
---|---|---|---|---|---|---|---|
client_id |
נדרש
מזהה הלקוח של האפליקציה. אפשר למצוא את הערך הזה בשדה API Console Credentials page. ב-Python, קוראים ל-method flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly']) |
||||||
redirect_uri |
נדרש
המדיניות הזו קובעת לאן שרת ה-API יפנה את המשתמש אוטומטית אחרי שהמשתמש ישלים את תהליך ההרשאה. הערך צריך להיות זהה לאחד ממזהי ה-URI המורשים להפניה אוטומטית בלקוח OAuth 2.0 שהגדרת ב- API Console
Credentials pageשל הלקוח. אם הערך הזה לא תואם
ל-URI מורשה להפניה אוטומטית עבור חשוב לשים לב שהסכמה כדי להגדיר את הערך הזה ב-Python, צריך להגדיר את מאפיין flow.redirect_uri = 'https://oauth2.example.com/code' |
||||||
scope |
נדרש
רשימה של היקפי הרשאות שמזהים את המשאבים שהאפליקציה יכולה לגשת אליהם בשם המשתמש. הערכים האלה מציינים את מסך ההסכמה ש-Google מציגה למשתמש. היקפי הרשאות מאפשרים לאפליקציה לבקש גישה רק למשאבים הנדרשים, וגם מאפשרים למשתמשים לשלוט ברמת הגישה שהם מעניקים לאפליקציה. לכן, יש קשר הפוך בין מספר ההיקפים המבוקשים לבין הסבירות לקבלת הסכמת המשתמש. ב-Python, משתמשים באותה שיטה שבה משתמשים כדי להגדיר את flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly']) כשהדבר אפשרי, מומלץ שהאפליקציה תבקש גישה להיקפי הרשאות לפי הקשר. בקשת גישה לנתוני משתמשים בהקשר מסוים, באמצעות הרשאה מצטברת, תעזור למשתמשים להבין בקלות למה האפליקציה צריכה את הגישה שהיא מבקשת. |
||||||
access_type |
מומלץ
השדה הזה מציין אם האפליקציה יכולה לרענן את אסימוני הגישה כשהמשתמש לא נוכח בדפדפן. ערכי הפרמטרים החוקיים הם אם האפליקציה צריכה לרענן את אסימוני הגישה כשהמשתמש לא נוכח בדפדפן, צריך להגדיר את הערך כ- ב-Python, מגדירים את הפרמטר authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true') |
||||||
state |
מומלץ
מציינת את כל ערך המחרוזת שבו האפליקציה משתמשת כדי לשמור על המצב בין בקשת ההרשאה לבין התגובה של שרת ההרשאות.
השרת מחזיר את הערך המדויק ששלחת כצמד אפשר להשתמש בפרמטר הזה לכמה מטרות, כמו להפנות את המשתמש
למשאב הנכון באפליקציה, שליחת נתונים חד-פעמיים (nonces) וצמצום זיוף בקשות בין אתרים. מכיוון שאפשר לנחש את ב-Python, מגדירים את הפרמטר authorization_url, state = flow.authorization_url( access_type='offline', state=sample_passthrough_value, include_granted_scopes='true') |
||||||
include_granted_scopes |
אופציונלי
מאפשרת לאפליקציות להשתמש בהרשאה מצטברת כדי לבקש גישה להיקפים נוספים בהקשר. אם מגדירים לפרמטר הזה את הערך ב-Python, מגדירים את הפרמטר authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true') |
||||||
enable_granular_consent |
אופציונלי
ברירת המחדל היא |
||||||
login_hint |
אופציונלי
אם האפליקציה יודעת איזה משתמש מנסה לבצע אימות, היא יכולה להשתמש בפרמטר הזה כדי לספק רמז לשרת האימות של Google. השרת משתמש ברמז כדי לפשט את תהליך ההתחברות, על ידי מילוי מראש של שדה האימייל בטופס הכניסה או על ידי בחירה בסשן המתאים של התחברות עם מספר חשבונות. מגדירים את ערך הפרמטר לכתובת אימייל או למזהה ב-Python, מגדירים את הפרמטר authorization_url, state = flow.authorization_url( access_type='offline', login_hint='None', include_granted_scopes='true') |
||||||
prompt |
אופציונלי
רשימת בקשות להצגת המשתמש מופרדת ברווחים ותלויות אותיות רישיות (case-sensitive). אם לא מציינים את הפרמטר הזה, המשתמש יקבל הודעה רק בפעם הראשונה שהפרויקט יבקש גישה. מידע נוסף זמין בקטע הצגת בקשה להסכמה מחדש. ב-Python, מגדירים את הפרמטר authorization_url, state = flow.authorization_url( access_type='offline', prompt='consent', include_granted_scopes='true') הערכים האפשריים הם:
|
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')Your application uses the client object to perform OAuth 2.0 operations, such as generating authorization request URLs and applying access tokens to HTTP requests.
Node.js
The code snippet below creates a google.auth.OAuth2
object, which defines the
parameters in the authorization request.
That object uses information from your client_secret.json file to identify your application. To ask for permissions from a user to retrieve an access token, you redirect them to a consent page. To create a consent page URL:
const {google} = require('googleapis'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI * from the client_secret.json file. To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Drive activity. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly' ]; // Generate a url that asks permissions for the Drive activity scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
הערה חשובה – refresh_token
מוחזר רק בהרשאה הראשונה.
כאן ניתן למצוא פרטים נוספים.
HTTP/REST
נקודת הקצה של OAuth 2.0 של Google נמצאת ב-https://accounts.google.com/o/oauth2/v2/auth
. אפשר לגשת
לנקודת הקצה הזו רק באמצעות HTTPS. חיבורי HTTP רגילים נדחו.
שרת ההרשאות של Google תומך בפרמטרים הבאים של מחרוזת השאילתה לאפליקציות של שרת אינטרנט:
פרמטרים | |||||||
---|---|---|---|---|---|---|---|
client_id |
נדרש
מזהה הלקוח של האפליקציה. אפשר למצוא את הערך הזה בשדה API Console Credentials page. |
||||||
redirect_uri |
נדרש
המדיניות הזו קובעת לאן שרת ה-API יפנה את המשתמש אוטומטית אחרי שהמשתמש ישלים את תהליך ההרשאה. הערך צריך להיות זהה לאחד ממזהי ה-URI המורשים להפניה אוטומטית בלקוח OAuth 2.0 שהגדרת ב- API Console
Credentials pageשל הלקוח. אם הערך הזה לא תואם
ל-URI מורשה להפניה אוטומטית עבור חשוב לשים לב שהסכמה |
||||||
response_type |
נדרש
המדיניות קובעת אם נקודת הקצה של Google OAuth 2.0 תחזיר קוד הרשאה. צריך להגדיר את ערך הפרמטר כ- |
||||||
scope |
נדרש
רשימת היקפים מופרדת ברווחים של המשאבים שמציינים את המשאבים שהאפליקציה יכולה לגשת אליהם בשם המשתמש. הערכים האלה מציינים את מסך ההסכמה ש-Google מציגה למשתמש. היקפי הרשאות מאפשרים לאפליקציה לבקש גישה רק למשאבים הנדרשים, וגם מאפשרים למשתמשים לשלוט ברמת הגישה שהם מעניקים לאפליקציה. לכן, יש קשר הפוך בין מספר ההיקפים המבוקשים לבין הסבירות לקבלת הסכמת המשתמש. כשהדבר אפשרי, מומלץ שהאפליקציה תבקש גישה להיקפי הרשאות לפי הקשר. בקשת גישה לנתוני משתמשים בהקשר מסוים, באמצעות הרשאה מצטברת, תעזור למשתמשים להבין בקלות למה האפליקציה צריכה את הגישה שהיא מבקשת. |
||||||
access_type |
מומלץ
השדה הזה מציין אם האפליקציה יכולה לרענן את אסימוני הגישה כשהמשתמש לא נוכח בדפדפן. ערכי הפרמטרים החוקיים הם אם האפליקציה צריכה לרענן את אסימוני הגישה כשהמשתמש לא נוכח בדפדפן, צריך להגדיר את הערך כ- |
||||||
state |
מומלץ
מציינת את כל ערך המחרוזת שבו האפליקציה משתמשת כדי לשמור על המצב בין בקשת ההרשאה לבין התגובה של שרת ההרשאות.
השרת מחזיר את הערך המדויק ששלחת כצמד אפשר להשתמש בפרמטר הזה לכמה מטרות, כמו להפנות את המשתמש
למשאב הנכון באפליקציה, שליחת נתונים חד-פעמיים (nonces) וצמצום זיוף בקשות בין אתרים. מכיוון שאפשר לנחש את |
||||||
include_granted_scopes |
אופציונלי
מאפשרת לאפליקציות להשתמש בהרשאה מצטברת כדי לבקש גישה להיקפים נוספים בהקשר. אם מגדירים לפרמטר הזה את הערך |
||||||
enable_granular_consent |
אופציונלי
ברירת המחדל היא |
||||||
login_hint |
אופציונלי
אם האפליקציה יודעת איזה משתמש מנסה לבצע אימות, היא יכולה להשתמש בפרמטר הזה כדי לספק רמז לשרת האימות של Google. השרת משתמש ברמז כדי לפשט את תהליך ההתחברות, על ידי מילוי מראש של שדה האימייל בטופס הכניסה או על ידי בחירה בסשן המתאים של התחברות עם מספר חשבונות. מגדירים את ערך הפרמטר לכתובת אימייל או למזהה |
||||||
prompt |
אופציונלי
רשימת בקשות להצגת המשתמש מופרדת ברווחים ותלויות אותיות רישיות (case-sensitive). אם לא מציינים את הפרמטר הזה, המשתמש יקבל הודעה רק בפעם הראשונה שהפרויקט יבקש גישה. מידע נוסף זמין בקטע הצגת בקשה להסכמה מחדש. הערכים האפשריים הם:
|
שלב 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 להרשאה באמצעות מסגרת אפליקציית האינטרנט של 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.writeHead(301, { "Location": authorizationUrl });
HTTP/REST
Sample redirect to Google's authorization server
An example URL is shown below, with line breaks and spaces for readability.
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
אחרי שיוצרים את כתובת ה-URL של הבקשה, יש להפנות את המשתמש אליה.
שרת OAuth 2.0 של Google מאמת את המשתמש ומקבל ממנו הסכמה כדי לאפשר לאפליקציה לגשת להיקפי ההרשאות המבוקשים. התגובה תישלח חזרה לאפליקציה שלך באמצעות כתובת האתר להפניה מחדש שציינת.
שלב 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 שמוגדר כברירת מחדל לקישורים של מערכת ההפעלה, שכולל גם את רכיבי ה-handler של קישורים לאפליקציות ל-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. if (req.url.startsWith('/oauth2callback')) { // Handle the OAuth 2.0 server response let q = url.parse(req.url, true).query; // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); }
HTTP/REST
כדי להחליף קוד הרשאה באסימון גישה, צריך לבצע קריאה לנקודת הקצה https://oauth2.googleapis.com/token
ולהגדיר את הפרמטרים הבאים:
שדות | |
---|---|
client_id |
מזהה הלקוח שהתקבל מ- API Console Credentials page. |
client_secret |
סוד הלקוח שהתקבל מ- API Console Credentials page. |
code |
קוד ההרשאה שהוחזר מהבקשה הראשונית. |
grant_type |
כפי שמוגדר במפרט OAuth 2.0, הערך בשדה הזה צריך להיות authorization_code . |
redirect_uri |
אחד ממזהי ה-URI של ההפניה האוטומטית שרשומים בפרויקט בשדה API Console
Credentials page של client_id הנתון. |
בקטע הקוד הבא מוצגת בקשה לדוגמה:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=https%3A//oauth2.example.com/code& grant_type=authorization_code
Google מגיבה לבקשה הזו על ידי החזרת אובייקט JSON שמכיל אסימון גישה לטווח קצר ואסימון רענון.
שימו לב שאסימון הרענון מוחזר רק אם האפליקציה הגדירה את הפרמטר access_type
לערך offline
בבקשה הראשונית שנשלחה לשרת ההרשאות של Google.
התשובה כוללת את השדות הבאים:
שדות | |
---|---|
access_token |
האסימון שהאפליקציה שלך שולחת כדי לאשר בקשת Google API. |
expires_in |
משך החיים שנותר של אסימון הגישה בשניות. |
refresh_token |
אסימון שניתן להשתמש בו כדי לקבל אסימון גישה חדש. אסימוני הרענון בתוקף עד
שהמשתמש יבטל את הגישה.
שוב, השדה הזה יופיע בתגובה הזו רק אם תגדירו את הפרמטר access_type
לערך offline בבקשה הראשונית לשרת ההרשאות של Google.
|
scope |
היקפי הגישה שהוענקה על ידי access_token , מבוטאים כרשימה של מחרוזות תלויות-רישיות ותלויות-רישיות. |
token_type |
סוג האסימון שהוחזר. בשלב הזה, הערך בשדה הזה מוגדר תמיד כ-Bearer . |
קטע הקוד הבא מציג תגובה לדוגמה:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
שגיאות
כשמחליפים את קוד ההרשאה באסימון גישה, יכול להיות שתופיע השגיאה הבאה במקום התגובה הצפויה. קודי שגיאות נפוצים והצעות לפתרונות מפורטים בהמשך.
invalid_grant
קוד ההרשאה שסופק אינו חוקי או בפורמט שגוי. מבקשים קוד חדש על ידי הפעלה מחדש של תהליך OAuth, כדי לבקש מהמשתמש שוב הסכמה.
קריאה ל-Google APIs
PHP
משתמשים באסימון הגישה כדי להפעיל את Google APIs. לשם כך, פועלים לפי השלבים הבאים:
- אם צריך להחיל אסימון גישה על אובייקט
Google\Client
חדש – לדוגמה אם אחסנתם את אסימון הגישה בסשן של משתמש – צריך להשתמש בשיטהsetAccessToken
:$client->setAccessToken($access_token);
- יוצרים אובייקט שירות ל-API שאליו רוצים להפעיל את הפונקציה. כדי ליצור אובייקט שירות, מספקים אובייקט
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
או ערך Bearer
של כותרת HTTP Authorization
. כשניתן, כותרת ה-HTTP עדיפה, כי מחרוזות השאילתה מופיעות בדרך כלל ביומני השרתים. ברוב המקרים, תוכלו להשתמש בספריית לקוח כדי להגדיר את הקריאות ל-Google APIs (לדוגמה, כשקוראים ל-Drive Files API).
אתם יכולים לנסות את כל ממשקי Google API ולראות את ההיקף שלהם במגרש המשחקים של OAuth 2.0.
דוגמאות ל-HTTP GET
קריאה לנקודת הקצה
drive.files
(ה-Drive Files API) באמצעות כותרת ה-HTTP Authorization: Bearer
עשויה להיראות כך. שימו לב שעליכם לציין אסימון גישה משלכם:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
הנה קריאה לאותו API עבור המשתמש המאומת באמצעות הפרמטר access_token
של מחרוזת השאילתה:
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
curl
דוגמאות
אפשר לבדוק את הפקודות האלה באמצעות אפליקציית שורת הפקודה curl
. הנה דוגמה לאפשרות של כותרת HTTP (השדה המועדף):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
לחלופין, אפשר לבחור את אפשרות הפרמטר של מחרוזת השאילתה:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
דוגמה מלאה
בדוגמה הבאה מדפיסים רשימת קבצים בפורמט JSON ב-Google Drive של המשתמש, אחרי שהמשתמש מבצע אימות ונותן את הסכמתו לכך שהאפליקציה תוכל לגשת למטא-נתונים של המשתמש ב-Drive.
PHP
כדי להריץ את הדוגמה הזו:
- בשדה 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'])) { $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } else { $client->authenticate($_GET['code']); $_SESSION['access_token'] = $client->getAccessToken(); $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); }
Python
בדוגמה הזו השתמשנו במסגרת Flask. היא
מריצה אפליקציית אינטרנט ב-http://localhost:8080
שמאפשרת לבדוק את תהליך OAuth 2.0. אם עוברים לכתובת ה-URL הזו, אמורים לראות ארבעה קישורים:
- בדיקה של בקשת API: הקישור הזה מפנה לדף שמנסה לבצע בקשת API לדוגמה. במקרה הצורך, היא תתחיל את תהליך ההרשאה. אם הפעולה בוצעה ללא שגיאות, הדף יציג את תגובת ה-API.
- בדיקה ישירה של תהליך האימות: הקישור הזה מפנה לדף שמנסה לשלוח את המשתמש דרך תהליך ההרשאה. האפליקציה מבקשת הרשאה לשלוח בקשות API מורשות בשם המשתמש.
- ביטול פרטי הכניסה הנוכחיים: הקישור מפנה לדף ש מבטל הרשאות שהמשתמש כבר העניק לאפליקציה.
- ניקוי פרטי הכניסה לסשן 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
ראשי.js
const http = require('http'); const https = require('https'); const url = require('url'); const { google } = require('googleapis'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. * To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Drive activity. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly' ]; // Generate a url that asks permissions for the Drive activity scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true }); /* Global variable that stores user credential in this code example. * ACTION ITEM for developers: * Store user's refresh token in your data store if * incorporating this code into your real app. * For more information on handling refresh tokens, * see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens */ let userCredential = null; async function main() { const server = http.createServer(async function (req, res) { // Example on redirecting user to Google's OAuth 2.0 server. if (req.url == '/') { res.writeHead(301, { "Location": authorizationUrl }); } // Receive the callback from Google's OAuth 2.0 server. if (req.url.startsWith('/oauth2callback')) { // Handle the OAuth 2.0 server response let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); /** Save credential to the global variable in case access token was refreshed. * ACTION ITEM: In a production app, you likely want to save the refresh token * in a secure persistent database instead. */ userCredential = tokens; // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } }); } } // Example on revoking a token if (req.url == '/revoke') { // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end(); } res.end(); }).listen(80); } main().catch(console.error);
HTTP/REST
בדוגמה הזו ל-Python נעשה שימוש ב-framework של Flask ובספרייה Requests כדי להדגים את תהליך השימוש ב-OAuth 2.0 באינטרנט. בתהליך הזה מומלץ להשתמש בספריית הלקוח של Google API ל-Python. (הדוגמה בכרטיסייה Python כן משתמשת בספריית הלקוח).
import json import flask import requests app = flask.Flask(__name__) CLIENT_ID = '123456789.apps.googleusercontent.com' CLIENT_SECRET = 'abc123' # Read from a file or environmental variable in a real app SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly' REDIRECT_URI = 'http://example.com/oauth2callback' @app.route('/') def index(): if 'credentials' not in flask.session: return flask.redirect(flask.url_for('oauth2callback')) credentials = json.loads(flask.session['credentials']) if credentials['expires_in'] <= 0: return flask.redirect(flask.url_for('oauth2callback')) else: headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])} req_uri = 'https://www.googleapis.com/drive/v2/files' r = requests.get(req_uri, headers=headers) return r.text @app.route('/oauth2callback') def oauth2callback(): if 'code' not in flask.request.args: auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code' '&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE) return flask.redirect(auth_uri) else: auth_code = flask.request.args.get('code') data = {'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code'} r = requests.post('https://oauth2.googleapis.com/token', data=data) flask.session['credentials'] = r.text return flask.redirect(flask.url_for('index')) if __name__ == '__main__': import uuid app.secret_key = str(uuid.uuid4()) app.debug = False app.run()
כללי אימות של כתובת אתר להפניה מחדש
Google מיישמת את כללי האימות הבאים כדי להפנות מזהי URI להפניה אוטומטית, כדי לעזור למפתחים לשמור על אבטחת האפליקציות שלהם. מזהי ה-URI של ההפניה חייבים לעמוד בכללים האלה. ההגדרות של דומיין, מארח, נתיב, שאילתה, סכימה ופרטי משתמש, כפי שמתואר בהמשך, מפורטות בסעיף 3 של RFC 3986.
כללי אימות | |
---|---|
סכמה |
מזהי URI להפניה אוטומטית חייבים להשתמש בסכימת HTTPS, ולא ב-HTTP פשוט. מזהי URI של Localhost (כולל מזהי URI של כתובות IP של Localhost) פטורים מהכלל הזה. |
מארח |
מארחים לא יכולים להיות כתובות 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
בעת קריאה ל-method generateAuthUrl
כדי לקבל את אסימון הרענון. אם כבר נתת לאפליקציה את ההרשאות הנדרשות מבלי להגדיר את המגבלות הנדרשות לקבלת אסימון רענון, יהיה עליך לאשר מחדש לאפליקציה לקבל אסימון רענון חדש.
כדי להגדיר refresh_token
מאוחר יותר, אפשר להשתמש בשיטה setCredentials
:
oauth2Client.setCredentials({ refresh_token: `STORED_REFRESH_TOKEN` });
אחרי שהלקוח יקבל אסימון רענון, אסימוני הגישה יושלמו וירעננו באופן אוטומטי בקריאה הבאה ל-API.
HTTP/REST
כדי לרענן אסימון גישה, האפליקציה שולחת לשרת ההרשאות של Google (https://oauth2.googleapis.com/token
) בקשת POST
מסוג HTTPS עם הפרמטרים הבאים:
שדות | |
---|---|
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
. במצבי שגיאה, מוחזר קוד המצב 400
של HTTP יחד עם קוד שגיאה.