המסמך הזה מסביר איך אפליקציות של שרת אינטרנט משתמשות בספריות לקוח של Google API או ב-Google נקודות קצה ב-OAuth 2.0 להטמעת הרשאת גישה מסוג OAuth 2.0 לצורך גישה ממשקי API של Google.
OAuth 2.0 מאפשר למשתמשים לשתף נתונים ספציפיים עם אפליקציה, תוך שמירה על שמות משתמש, סיסמאות ומידע אחר באופן פרטי. לדוגמה, אפליקציה יכולה להשתמש ב-OAuth 2.0 כדי לקבל הרשאה למשתמשים לאחסן קבצים ב-Google Drive שלהם.
התהליך הזה ב-OAuth 2.0 מיועד במיוחד להרשאה של משתמשים. מיועד לאפליקציות שיכולים לאחסן מידע סודי ולשמור על מצבו. שרת אינטרנט עם הרשאה מתאימה אפליקציה יכולה לגשת ל-API בזמן שהמשתמש מקיים אינטראקציה עם האפליקציה או אחרי יצא מהאפליקציה.
יישומים של שרת אינטרנט משתמשים לעתים קרובות גם ב- לחשבונות שירות כדי לאשר בקשות API, במיוחד במהלך קריאה לממשקי Cloud API לקבל גישה על נתונים שמבוססים על פרויקטים ולא על נתונים ספציפיים למשתמש. אפליקציות בשרת האינטרנט יכולות להשתמש בשירות חשבונות בשילוב עם הרשאת משתמש.
ספריות לקוח
הדוגמאות הספציפיות לשפה בדף הזה משתמשות ספריות הלקוח של Google API להטמעה הרשאת OAuth 2.0. כדי להריץ את דוגמאות הקוד, צריך קודם להתקין את עבור השפה שלך.
כשמשתמשים בספריית לקוח של Google API כדי לטפל בזרימת OAuth 2.0 של האפליקציה, הלקוח מבצעת פעולות רבות שהאפליקציה הייתה צריכה לבצע בעצמה. עבור לדוגמה, הוא קובע מתי האפליקציה יכולה להשתמש באסימוני גישה מאוחסנים או לרענן אותם, וגם מתי האפליקציה צריכה לקבל שוב הסכמה. ספריית הלקוח גם יוצרת הפניה אוטומטית נכונה כתובות URL ועוזרות להטמיע handlers של הפניות אוטומטיות, שמחליפים קודי הרשאה באסימוני גישה.
ספריות לקוח של Google API לאפליקציות בצד השרת זמינות בשפות הבאות:
דרישות מוקדמות
הפעלת ממשקי API לפרויקט
כל אפליקציה שקוראת ל-Google APIs צריכה להפעיל את ממשקי ה-API האלה API Console
כדי להפעיל API לפרויקט:
- 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.
- בוחרים בסוג האפליקציה 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.
-
לקוח Node.js של Google APIs:
npm install googleapis crypto express express-session
HTTP/REST
אין צורך להתקין ספריות כדי להפעיל ישירות את OAuth 2.0 נקודות קצה (endpoints).
קבלת אסימוני גישה מסוג OAuth 2.0
השלבים הבאים מראים איך האפליקציה מקיימת אינטראקציה עם שרת OAuth 2.0 של Google כדי לקבל הסכמה של משתמש לבצע בקשת API בשם המשתמש. האפליקציה צריכה להכיל את הפרטים האלה הסכמה לפני שיוכל להוציא לפועל בקשת Google API שמחייבת הרשאת משתמש.
הרשימה הבאה מסכמת במהירות את השלבים הבאים:
- האפליקציה מזהה את ההרשאות שדרושה לה.
- האפליקציה מפנה את המשתמש אוטומטית ל-Google עם רשימת ה הרשאות.
- המשתמש מחליט אם להעניק את ההרשאות לאפליקציה.
- האפליקציה שלך מקבלת מידע לגבי מה שהמשתמש החליט.
- אם המשתמש העניק את ההרשאות הנדרשות, האפליקציה מאחזרת את האסימונים שנדרשים כדי לשלוח בקשות API בשם המשתמש.
שלב 1: הגדרת פרמטרים של הרשאה
השלב הראשון הוא יצירה של בקשת הרשאה. הבקשה הזו מגדירה פרמטרים לזהות את האפליקציה שלך ולהגדיר את ההרשאות שהמשתמש יתבקש להעניק להן את האפליקציה שלך.
- אם אתם משתמשים בספריית לקוח של Google לצורך אימות והרשאה של OAuth 2.0, אתם יצירה והגדרה של אובייקט שמגדיר את הפרמטרים האלה.
- אם תתקשרו ישירות לנקודת הקצה של Google OAuth 2.0, ייווצרו כתובת URL ותגדירו בכתובת האתר הזו.
הכרטיסיות הבאות מגדירות את הפרמטרים הנתמכים של ההרשאות לאפליקציות של שרת אינטרנט. דוגמאות ספציפיות לשפה מראות גם איך להשתמש בספריית לקוח או בספריית הרשאות כדי להגדיר אובייקט שמגדיר את הפרמטרים האלה.
PHP
קטע הקוד שבהמשך יוצר אובייקט Google\Client()
, שמגדיר את
הפרמטרים בבקשת ההרשאה.
האובייקט הזה משתמש במידע מהקובץ client_secret.json כדי לזהות
תרגום מכונה. (מידע נוסף זמין במאמר יצירת פרטי כניסה להרשאות).
). האובייקט מזהה גם את היקפי ההרשאות שהאפליקציה מבקשת הרשאה
כדי לגשת אל כתובת ה-URL של נקודת הקצה (endpoint) של האימות של האפליקציה.
שרת OAuth 2.0 של Google. לבסוף, הקוד מגדיר את הערכים האופציונליים access_type
include_granted_scopes
פרמטרים.
לדוגמה, הקוד הזה מבקש גישה לקריאה בלבד, אופליין ב-Google Drive:
$client = new Google\Client(); // Required, call the setAuthConfig function to load authorization credentials from // client_secret.json file. $client->setAuthConfig('client_secret.json'); // Required, to set the scope value, call the addScope function $client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY); // Required, call the setRedirectUri function to specify a valid redirect URI for the // provided client_id $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // Recommended, offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType('offline'); // Recommended, call the setState function. Using a state value can increase your assurance that // an incoming connection is the result of an authentication request. $client->setState($sample_passthrough_value); // Optional, if your application knows which user is trying to authenticate, it can use this // parameter to provide a hint to the Google Authentication Server. $client->setLoginHint('hint@example.com'); // Optional, call the setPrompt function to set "consent" will prompt the user for consent $client->setPrompt('consent'); // Optional, call the setIncludeGrantedScopes function with true to enable incremental // authorization $client->setIncludeGrantedScopes(true);
Python
קטע הקוד הבא משתמש במודול google-auth-oauthlib.flow
כדי ליצור
בקשת ההרשאה.
הקוד בונה אובייקט Flow
שמזהה את האפליקציה שלכם באמצעות
מידע מהקובץ client_secret.json שהורדתם אחרי
וליצור פרטי כניסה להרשאה. האובייקט הזה מזהה גם
היקפי ההרשאות שהאפליקציה שלך מבקשת הרשאה לגשת אליהם ואת כתובת ה-URL של האפליקציה
נקודת קצה (endpoint) מאומתת, שתטפל בתגובה משרת OAuth 2.0 של Google. לבסוף, הקוד
מגדירה את הפרמטרים האופציונליים access_type
ו-include_granted_scopes
.
לדוגמה, הקוד הזה מבקש גישה לקריאה בלבד, אופליין ב-Google Drive:
import google.oauth2.credentials import google_auth_oauthlib.flow # Required, call the from_client_secrets_file method to retrieve the client ID from a # client_secret.json file. The client ID (from that file) and access scopes are required. (You can # also use the from_client_config method, which passes the client configuration as it originally # appeared in a client secrets file but doesn't access the file itself.) flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly']) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. flow.redirect_uri = 'https://www.example.com/oauth2callback' # Generate URL for request to Google's OAuth 2.0 server. # Use kwargs to set optional request parameters. authorization_url, state = flow.authorization_url( # Recommended, enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Optional, enable incremental authorization. Recommended as a best practice. include_granted_scopes='true', # Optional, if your application knows which user is trying to authenticate, it can use this # parameter to provide a hint to the Google Authentication Server. login_hint='hint@example.com', # Optional, set prompt to 'consent' will prompt the user for consent prompt='consent')
Ruby
משתמשים בקובץ client_secrets.json שיצרתם כדי להגדיר אובייקט לקוח ב- תרגום מכונה. כשמגדירים אובייקט לקוח, צריך לציין את היקפי ההרשאות שהאפליקציה צריכה יחד עם כתובת ה-URL של נקודת הקצה (endpoint) לאימות של האפליקציה, שתטפל בתגובה משרת OAuth 2.0.
לדוגמה, הקוד הזה מבקש גישה לקריאה בלבד, אופליין ב-Google Drive:
require 'google/apis/drive_v3' require "googleauth" require 'googleauth/stores/redis_token_store' client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json') scope = 'https://www.googleapis.com/auth/drive.metadata.readonly' token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')
האפליקציה משתמשת באובייקט הלקוח כדי לבצע פעולות OAuth 2.0, כמו יצירת כתובות URL של בקשות הרשאה והחלת אסימוני גישה על בקשות HTTP.
Node.js
קטע הקוד הבא יוצר אובייקט google.auth.OAuth2
, שמגדיר את
הפרמטרים בבקשת ההרשאה.
האובייקט הזה משתמש במידע מהקובץ client_secret.json כדי לזהות את האפליקציה. שפת תרגום כדי לבקש ממשתמש הרשאה לאחזר אסימון גישה, אתם מפנים אותו לדף הסכמה. כדי ליצור כתובת URL של דף הסכמה:
const {google} = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI * from the client_secret.json file. To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Drive activity. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly' ]; // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // Generate a url that asks permissions for the Drive activity scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true, // Include the state parameter to reduce the risk of CSRF attacks. state: state });
הערה חשובה – השדה refresh_token
מוחזר רק
אישור. פרטים נוספים
כאן.
HTTP/REST
נקודת הקצה מסוג OAuth 2.0 של Google היא https://accounts.google.com/o/oauth2/v2/auth
. הזה
אפשר לגשת לנקודת הקצה (endpoint) רק באמצעות HTTPS. חיבורי HTTP רגילים נדחים.
שרת ההרשאות של Google תומך בפרמטרים הבאים של מחרוזת שאילתה לאינטרנט אפליקציות שרת:
פרמטרים | |||||||
---|---|---|---|---|---|---|---|
client_id |
חובה
מזהה הלקוח של האפליקציה. אפשר למצוא את הערך הזה API Console Credentials page. |
||||||
redirect_uri |
חובה
קובע להיכן שרת ה-API מפנה את המשתמש מחדש אחרי שהמשתמש משלים את
תהליך ההרשאה. הערך חייב להתאים בדיוק לאחד ממזהי ה-URI המורשים להפניה מחדש עבור
לקוח OAuth 2.0, שאותו הגדרת באפליקציית הלקוח
API Console
Credentials page. אם הערך הזה לא תואם
ה-URI הייעודי להפניה אוטומטית ב- חשוב לשים לב לסכימה |
||||||
response_type |
חובה
המדיניות קובעת אם נקודת הקצה מסוג Google OAuth 2.0 מחזירה קוד הרשאה. צריך להגדיר את ערך הפרמטר כ- |
||||||
scope |
חובה
א' קובץ מופרד ברווחים רשימת היקפים שמזהים את המשאבים שהאפליקציה יכולה לגשת אליהם בשם המשתמש. הערכים האלה קובעים את מסך ההסכמה ש-Google מציגה משתמש. היקפי הרשאות מאפשרים לאפליקציה לבקש גישה רק למשאבים שהיא צריכה ובמקביל גם מאפשרים למשתמשים לשלוט בכמות הגישה שהם מעניקים תרגום מכונה. כך יש קשר הפוך בין מספר ההיקפים המבוקשים והסבירות לקבל את הסכמת המשתמש. אנחנו ממליצים שהאפליקציה תבקש גישה להיקפי הרשאות בהתאם להקשר ככל האפשר. באמצעות בקשת גישה לנתוני המשתמשים בהקשר המתאים, הרשאה מצטברת, עוזרת למשתמשים לבצע בקלות רבה יותר להבין מדוע האפליקציה שלך זקוקה להרשאות הגישה שהיא מבקשת. |
||||||
access_type |
המלצות
שדה זה מציין אם האפליקציה יכולה לרענן את אסימוני הגישה כשהמשתמש לא נמצא
בדפדפן. ערכי הפרמטרים החוקיים הם צריך להגדיר את הערך כ- |
||||||
state |
המלצות
מציינת כל ערך מחרוזת שהאפליקציה שלכם משתמשת בו כדי לשמור על מצב בין
בקשת ההרשאה והתגובה של שרת ההרשאות.
השרת מחזיר את הערך המדויק שאתם שולחים בתור צמד אפשר להשתמש בפרמטר הזה לכמה מטרות, כמו הפניית המשתמש אל
המשאב הנכון באפליקציה, שליחת צפנים חד-פעמיים וצמצום בקשות בין אתרים
מזויף. מכיוון שניתן לנחש את |
||||||
include_granted_scopes |
אופציונלי
מאפשרת לאפליקציות להשתמש בהרשאה מצטברת כדי לבקש גישה לשירותים נוספים
היקפים בהקשר המתאים. אם מגדירים את ערך הפרמטר הזה כ- |
||||||
enable_granular_consent |
אופציונלי
ברירת המחדל היא כש-Google מאפשרת הרשאות מפורטות לאפליקציה, הפרמטר הזה לא ולא תהיה לכך השפעה רבה יותר. |
||||||
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
משלב 1 שיטהgenerateAuthUrl
לבקשת גישה משרת 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
נקודת הקצה (endpoint) של ההרשאה מוצגת בתוך סוכן משתמש מוטמע שאסור להפעיל על ידי Google כללי מדיניות OAuth 2.0.
Android
מפתחי Android עשויים להיתקל בהודעת השגיאה הזו כשהם פותחים בקשות הרשאה ב
android.webkit.WebView
מפתחים צריכים להשתמש במקום זאת בספריות Android כמו
כניסה באמצעות חשבון Google ל-Android או OpenID Foundation
AppAuth ל-Android.
מפתחי אתרים עשויים להיתקל בשגיאה הזו כשאפליקציה ל-Android פותחת קישור כללי לאינטרנט סוכן משתמש מוטמע ומשתמש מנווט לנקודת הקצה של הרשאת OAuth 2.0 של Google דרך באתר שלך. המפתחים צריכים לאפשר לקישורים כלליים להיפתח ב-handler של הקישור שמוגדר כברירת מחדל של במערכת ההפעלה, שכוללת גם קישורים לאפליקציות ל-Android או את אפליקציית ברירת המחדל של הדפדפן. כרטיסיות מותאמות אישית ב-Android היא גם אפשרות נתמכת.
iOS
מפתחי iOS ו-macOS עשויים להיתקל בשגיאה הזו כשהם יפתחו בקשות הרשאה
WKWebView
מפתחים צריכים במקום זאת להשתמש בספריות iOS כמו
כניסה באמצעות חשבון Google ל-iOS או OpenID Foundation
AppAuth ל-iOS.
מפתחי אתרים עשויים להיתקל בשגיאה הזו כשאפליקציה ל-iOS או ל-macOS פותחת קישור כללי לאינטרנט
סוכן משתמש מוטמע ומשתמש מנווט לנקודת הקצה של הרשאת OAuth 2.0 של Google דרך
באתר שלך. המפתחים צריכים לאפשר לקישורים כלליים להיפתח ב-handler של הקישור שמוגדר כברירת מחדל של
במערכת ההפעלה, שכוללת גם
קישורים אוניברסליים
או את אפליקציית ברירת המחדל של הדפדפן.
SFSafariViewController
היא גם אפשרות נתמכת.
org_internal
מזהה הלקוח ב-OAuth שצוין בבקשה הוא חלק מפרויקט שמגביל את הגישה לחשבונות Google במסגרת ספציפי ארגון ב-Google Cloud. למידע נוסף על אפשרות ההגדרה הזו, אפשר לעיין במאמר סוג המשתמש בקטע 'הגדרת מסך העזרה של מסך ההסכמה ב-OAuth'.
invalid_client
סוד הלקוח ב-OAuth שגוי. כדאי לקרוא את לקוח OAuth , כולל מזהה הלקוח והסוד שמשמשים לבקשה הזו.
invalid_grant
כשמרעננים אסימון גישה או משתמשים הרשאה מצטברת, ייתכן שתוקף האסימון פג או שהתוקף שלו בוטל תוקף. צריך לאמת שוב את המשתמש ולבקש את הסכמת המשתמש כדי לקבל אסימונים חדשים. אם ממשיכים כדי לראות את השגיאה הזו, צריך לוודא שהאפליקציה הוגדרה בצורה נכונה באמצעות האסימונים והפרמטרים הנכונים בבקשה שלכם. אחרת, יכול להיות שלחשבון המשתמש נמחק או הושבת.
redirect_uri_mismatch
הredirect_uri
שהועבר בבקשת ההרשאה לא תואם לחשבון מורשה
ה-URI להפניה אוטומטית במזהה הלקוח ב-OAuth. לבדוק את מזהי ה-URI המורשים להפניה אוטומטית
Google API Console Credentials page
הפרמטר redirect_uri
עשוי להתייחס לתהליך של OAuth מחוץ למסגרת (OOB) שכולל
הוצא משימוש ולא נתמך יותר. עיינו ב
מדריך ההעברה כדי לעדכן את
של Google Analytics.
invalid_request
יש בעיה בבקשה ששלחת. יכולות להיות לכך כמה סיבות:
- פורמט הבקשה שגוי
- בבקשה היו חסרים פרמטרים נדרשים
- הבקשה משתמשת בשיטת הרשאה ש-Google לא תומכת בה. אימות OAuth משתמשת בשיטת שילוב מומלצת.
שלב 4: טיפול בתגובה לשרת OAuth 2.0
שרת OAuth 2.0 מגיב לבקשת הגישה של האפליקציה באמצעות כתובת ה-URL שצוינה בבקשה.
אם המשתמש יאשר את בקשת הגישה, התשובה תכיל קוד הרשאה. אם המיקום המשתמש לא מאשר את הבקשה, התשובה תכיל הודעת שגיאה. קוד ההרשאה או הודעת השגיאה שמוחזרים לשרת האינטרנט מופיעים בשאילתה String (מחרוזת), כפי שמוצג בהמשך:
תגובת שגיאה:
https://oauth2.example.com/auth?error=access_denied
תגובת קוד הרשאה:
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
דוגמה של תגובת שרת OAuth 2.0
כדי לבדוק את התהליך הזה, לוחצים על כתובת ה-URL לדוגמה הבאה, הרשאת קריאה בלבד להצגת מטא-נתונים של קבצים ב-Google Drive:
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
בסיום התהליך ב-OAuth 2.0, תופנו אל
http://localhost/oauth2callback
, שככל הנראה יניב
404 NOT FOUND
, אלא אם המחשב המקומי שלך מגישה קובץ בכתובת זו.
השלב הבא מספק פרטים נוספים על המידע שמוחזר ב-URI כשהמשתמש
מפנה מחדש לאפליקציה שלך.
שלב 5: קוד ההרשאה של Exchange לרענון וגישה אסימונים
אחרי ששרת האינטרנט מקבל את קוד ההרשאה, הוא יכול להחליף את קוד ההרשאה לאסימון גישה.
PHP
כדי להחליף קוד הרשאה באסימון גישה, משתמשים ב-authenticate
method:
$client->authenticate($_GET['code']);
אפשר לאחזר את אסימון הגישה באמצעות ה-method getAccessToken
:
$access_token = $client->getAccessToken();
Python
בדף הקריאה החוזרת, צריך להשתמש בספרייה google-auth
כדי לאמת את ההרשאה
תגובת השרת. אחר כך משתמשים בשיטה flow.fetch_token
כדי להחליף את ההרשאה
הקוד בתגובה לאסימון גישה:
state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'], state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store the credentials in the session. # ACTION ITEM for developers: # Store user's access and refresh tokens in your data store if # incorporating this code into your real app. credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes}
Ruby
בדף הקריאה החוזרת, צריך להשתמש בספרייה googleauth
כדי לאמת את שרת ההרשאות
תשובה. משתמשים בשיטה authorizer.handle_auth_callback_deferred
כדי לשמור את
קוד הרשאה ולהפנות בחזרה לכתובת האתר שביקשה הרשאה במקור. הזה
דוחה את החלפת הקוד על ידי הסתרה זמנית של התוצאות בסשן של המשתמש.
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url
Node.js
כדי להחליף קוד הרשאה באסימון גישה, משתמשים ב-getToken
method:
const url = require('url'); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); });
HTTP/REST
כדי להחליף קוד הרשאה באסימון גישה, קוראים אל
https://oauth2.googleapis.com/token
ולהגדיר את הפרמטרים הבאים:
שדות | |
---|---|
client_id |
מזהה הלקוח שהתקבל מ- API Console Credentials page. |
client_secret |
סוד הלקוח שהתקבל מ- API Console Credentials page. |
code |
קוד ההרשאה שהוחזר מהבקשה הראשונית. |
grant_type |
כפי שמוגדר ב-OAuth 2.0
, הערך של השדה הזה צריך להיות authorization_code . |
redirect_uri |
אחד ממזהי ה-URI להפניה מחדש המפורטים עבור הפרויקט שלך
API Console
Credentials page עבור הערך הנתון
client_id . |
קטע הקוד הבא מציג בקשה לדוגמה:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=https%3A//oauth2.example.com/code& grant_type=authorization_code
Google מגיבה לבקשה הזו על ידי החזרת אובייקט JSON שמכיל גישה לטווח קצר
וגם אסימון רענון.
לתשומת ליבכם, אסימון הרענון מוחזר רק אם האפליקציה שלכם מגדירה את access_type
ל-offline
בבקשה הראשונית
שרת ההרשאות.
התשובה תכיל את השדות הבאים:
שדות | |
---|---|
access_token |
האסימון שהאפליקציה שלכם שולחת כדי לאשר בקשת Google API. |
expires_in |
משך החיים שנותר לאסימון הגישה, בשניות. |
refresh_token |
אסימון שאפשר להשתמש בו כדי לקבל אסימון גישה חדש. אסימוני הרענון תקפים עד
המשתמש מבטל את הגישה.
שוב, השדה הזה יוצג בתשובה הזו רק אם מגדירים את access_type
ל-offline בבקשה הראשונית לשרת ההרשאות של Google.
|
scope |
היקפי הגישה שהוענקה על ידי access_token , מוצגים כרשימה של
מחרוזות תלויות-רישיות, שמופרדות ברווחים. |
token_type |
סוג האסימון המוחזר. בשלב הזה, הערך בשדה הזה תמיד מוגדר כ-
Bearer |
בקטע הקוד הבא מוצגת תגובה לדוגמה:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
שגיאות
כשמחליפים את קוד ההרשאה באסימון גישה, עלולים להיתקל במצבים הבאים במקום התגובה הצפויה. קודי שגיאה נפוצים ופתרונות מוצעים הם שמפורטות בהמשך.
invalid_grant
קוד ההרשאה שסופק אינו חוקי או בפורמט שגוי. בקשת קוד חדש עד הפעלה מחדש של תהליך OAuth כדי לבקש הסכמה מהמשתמש שוב.
קריאה ל-Google APIs
PHP
משתמשים באסימון הגישה כדי לקרוא ל-Google APIs. לשם כך מבצעים את השלבים הבאים:
- אם צריך להחיל אסימון גישה על אובייקט
Google\Client
חדש – לדוגמה, אם אחסנתם את אסימון הגישה בסשן של משתמש — השתמשוsetAccessToken
method:$client->setAccessToken($access_token);
- יוצרים אובייקט שירות ל-API שאליו רוצים לקרוא. אתם יוצרים אובייקט שירות לפי
שליחת אובייקט
Google\Client
מורשה ל-constructor של ה-API שאליו רוצים להתקשר. לדוגמה, כדי להפעיל את Drive API:$drive = new Google\Service\Drive($client);
- שולחים בקשות לשירות ה-API באמצעות
הממשק שסופק על ידי אובייקט השירות.
לדוגמה, כדי להציג רשימה של הקבצים ב-Google Drive של המשתמש המאומת:
$files = $drive->files->listFiles(array())->getItems();
Python
לאחר קבלת אסימון גישה, האפליקציה שלך יכולה להשתמש באסימון הזה כדי לאשר בקשות API מטעם חשבון משתמש או חשבון שירות מסוימים. שימוש בפרטי כניסה להרשאה ספציפית למשתמש כדי ליצור אובייקט שירות ל-API שאליו רוצים לקרוא, ואז להשתמש באובייקט כדי ליצור בקשות API מורשות.
- יוצרים אובייקט שירות ל-API שאליו רוצים לקרוא. אתם יוצרים אובייקט שירות לפי
קריאה ל-method
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
לאחר שהאפליקציה שלך מקבלת אסימון גישה, אפשר להשתמש באסימון כדי לבצע קריאות
API בשם נתון
חשבון משתמש, אם היקפי הגישה הנדרשים על ידי ה-API הוענקו. כדי לעשות את זה, צריך לכלול
אסימון הגישה בבקשה ל-API על ידי הכללת שאילתת access_token
או ערך Bearer
של כותרת HTTP בAuthorization
. כשהדבר אפשרי,
עדיף להשתמש בכותרת HTTP, כי מחרוזות השאילתה בדרך כלל גלויות ביומני השרת. במרבית
במקרים מסוימים תוכלו להשתמש בספריית לקוח כדי להגדיר את הקריאות ל-Google APIs (לדוגמה,
שליחת קריאה ל-Drive Files API).
אפשר לנסות את כל ממשקי ה-API של Google ולצפות בהיקף שלהם בקישור OAuth 2.0 Playground
דוגמאות ל-HTTP GET
קריאה ל
drive.files
נקודת הקצה (Drive Files API) באמצעות Authorization: Bearer
HTTP
עשויה להיראות כך. שימו לב שתצטרכו לציין אסימון גישה משלכם:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
זוהי קריאה לאותו API בשביל המשתמש המאומת באמצעות access_token
פרמטר של מחרוזת שאילתה:
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
curl
דוגמאות
אפשר לבדוק את הפקודות האלה באמצעות אפליקציית שורת הפקודה curl
. הנה
דוגמה שמשתמשת באפשרות של כותרת HTTP (מועדף):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
לחלופין, אפשרות הפרמטר של מחרוזת השאילתה:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
דוגמה מלאה
הדוגמה הבאה מדפיסה רשימה בפורמט JSON של קבצים ב-Google Drive של המשתמש אחרי המשתמש מאמת את ומעניק את הסכמתו לאפליקציה כדי לגשת למטא-נתונים של המשתמש ב-Drive.
PHP
כדי להריץ את הדוגמה הזו:
- בקטע 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
בדוגמה הזו נשתמש ב-framework של Flask. הוא
מריצה אפליקציית אינטרנט ב-http://localhost:8080
שמאפשרת לבדוק את OAuth 2.0
. אם עוברים לכתובת ה-URL הזו, אמורים להופיע 4 קישורים:
- בדיקה של בקשת API: הקישור הזה מפנה לדף שמנסה להפעיל API לדוגמה בקשה. אם יהיה צורך, יתחיל תהליך ההרשאה. אם הפעולה בוצעה ללא שגיאות, הדף יציג את תגובת API.
- בדיקה ישירה של תהליך האימות: הקישור הזה מפנה לדף שמנסה לשלוח את המשתמש באמצעות תהליך ההרשאה. האפליקציה מבקשת הרשאה ל להגיש בקשות API מורשות בשם המשתמש.
- ביטול פרטי הכניסה הנוכחיים: הקישור הזה מפנה לדף ש מבטל את ההרשאות שהמשתמש כבר העניק לאפליקציה.
- ניקוי פרטי הכניסה של Flask: הקישור הזה מנקה את פרטי הכניסה להרשאה מאוחסנים בסשן של Flask. כך אפשר לראות מה יקרה אם משתמש שכבר שקיבלו הרשאה לאפליקציה ניסו לבצע בקשת API בסשן חדש. היא גם מאפשרת תגובת ה-API שהאפליקציה שלכם הייתה מקבלת אם משתמש היה מבטל את ההרשאות שהוענקו והאפליקציה עדיין ניסתה לאשר בקשה באמצעות אסימון גישה שבוטל.
# -*- coding: utf-8 -*- import os import flask import requests import google.oauth2.credentials import google_auth_oauthlib.flow import googleapiclient.discovery # This variable specifies the name of a file that contains the OAuth 2.0 # information for this application, including its client_id and client_secret. CLIENT_SECRETS_FILE = "client_secret.json" # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account and requires requests to use an SSL connection. SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'] API_SERVICE_NAME = 'drive' API_VERSION = 'v2' app = flask.Flask(__name__) # Note: A secret key is included in the sample so that it works. # If you use this code in your application, replace this with a truly secret # key. See https://flask.palletsprojects.com/quickstart/#sessions. app.secret_key = 'REPLACE ME - this value is here as a placeholder.' @app.route('/') def index(): return print_index_table() @app.route('/test') def test_api_request(): if 'credentials' not in flask.session: return flask.redirect('authorize') # Load credentials from the session. credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) drive = googleapiclient.discovery.build( API_SERVICE_NAME, API_VERSION, credentials=credentials) files = drive.files().list().execute() # Save credentials back to session in case access token was refreshed. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. flask.session['credentials'] = credentials_to_dict(credentials) return flask.jsonify(**files) @app.route('/authorize') def authorize(): # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES) # The URI created here must exactly match one of the authorized redirect URIs # for the OAuth 2.0 client, which you configured in the API Console. If this # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch' # error. flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true') # Store the state so the callback can verify the auth server response. flask.session['state'] = state return flask.redirect(authorization_url) @app.route('/oauth2callback') def oauth2callback(): # Specify the state when creating the flow in the callback so that it can # verified in the authorization server response. state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES, state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) # Use the authorization server's response to fetch the OAuth 2.0 tokens. authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store credentials in the session. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. credentials = flow.credentials flask.session['credentials'] = credentials_to_dict(credentials) return flask.redirect(flask.url_for('test_api_request')) @app.route('/revoke') def revoke(): if 'credentials' not in flask.session: return ('You need to <a href="/authorize">authorize</a> before ' + 'testing the code to revoke credentials.') credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) revoke = requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'}) status_code = getattr(revoke, 'status_code') if status_code == 200: return('Credentials successfully revoked.' + print_index_table()) else: return('An error occurred.' + print_index_table()) @app.route('/clear') def clear_credentials(): if 'credentials' in flask.session: del flask.session['credentials'] return ('Credentials have been cleared.<br><br>' + print_index_table()) def credentials_to_dict(credentials): return {'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes} def print_index_table(): return ('<table>' + '<tr><td><a href="/test">Test an API request</a></td>' + '<td>Submit an API request and see a formatted JSON response. ' + ' Go through the authorization flow if there are no stored ' + ' credentials for the user.</td></tr>' + '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' + '<td>Go directly to the authorization flow. If there are stored ' + ' credentials, you still might not be prompted to reauthorize ' + ' the application.</td></tr>' + '<tr><td><a href="/revoke">Revoke current credentials</a></td>' + '<td>Revoke the access token associated with the current user ' + ' session. After revoking credentials, if you go to the test ' + ' page, you should see an <code>invalid_grant</code> error.' + '</td></tr>' + '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' + '<td>Clear the access token currently stored in the user session. ' + ' After clearing the token, if you <a href="/test">test the ' + ' API request</a> again, you should go back to the auth flow.' + '</td></tr></table>') if __name__ == '__main__': # When running locally, disable OAuthlib's HTTPs verification. # ACTION ITEM for developers: # When running in production *do not* leave this option enabled. os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # Specify a hostname and port that are set as a valid redirect URI # for your API project in the Google API Console. app.run('localhost', 8080, debug=True)
Ruby
בדוגמה הזו נעשה שימוש ב-framework של Sinatra.
require 'google/apis/drive_v3' require 'sinatra' require 'googleauth' require 'googleauth/stores/redis_token_store' configure do enable :sessions set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json') set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback') end get '/' do user_id = settings.client_id.id credentials = settings.authorizer.get_credentials(user_id, request) if credentials.nil? redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request) end drive = Google::Apis::DriveV3::DriveService.new files = drive.list_files(options: { authorization: credentials }) "<pre>#{JSON.pretty_generate(files.to_h)}</pre>" end get '/oauth2callback' do target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url end
Node.js
כדי להריץ את הדוגמה הזו:
-
בקטע API Console, צריך להוסיף את כתובת ה-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 משתמשים ב-framework של Flask ובספרייה בקשות להדגים את פרוטוקול OAuth זרימת אינטרנט 2.0. בתהליך הזה מומלץ להשתמש בספריית הלקוח של Google API ל-Python. (ה בכרטיסייה Python כן משתמשת בספריית הלקוח).
import json import flask import requests app = flask.Flask(__name__) CLIENT_ID = '123456789.apps.googleusercontent.com' CLIENT_SECRET = 'abc123' # Read from a file or environmental variable in a real app SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly' REDIRECT_URI = 'http://example.com/oauth2callback' @app.route('/') def index(): if 'credentials' not in flask.session: return flask.redirect(flask.url_for('oauth2callback')) credentials = json.loads(flask.session['credentials']) if credentials['expires_in'] <= 0: return flask.redirect(flask.url_for('oauth2callback')) else: headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])} req_uri = 'https://www.googleapis.com/drive/v2/files' r = requests.get(req_uri, headers=headers) return r.text @app.route('/oauth2callback') def oauth2callback(): if 'code' not in flask.request.args: state = str(uuid.uuid4()) flask.session['state'] = state auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code' '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI, SCOPE, state) return flask.redirect(auth_uri) else: if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']: return 'State mismatch. Possible CSRF attack.', 400 auth_code = flask.request.args.get('code') data = {'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code'} r = requests.post('https://oauth2.googleapis.com/token', data=data) flask.session['credentials'] = r.text return flask.redirect(flask.url_for('index')) if __name__ == '__main__': import uuid app.secret_key = str(uuid.uuid4()) app.debug = False app.run()
הפניה אוטומטית של כללי אימות ה-URI
Google מחילה את כללי האימות הבאים כדי להפנות מזהי URI להפניה אוטומטית על מנת לעזור למפתחים שישמרו על אבטחת האפליקציות שלהם. מזהי ה-URI להפניה אוטומטית חייבים לפעול בהתאם לכללים האלה. צפייה RFC 3986 סעיף 3 עבור הגדרה של דומיין, מארח, נתיב, שאילתה, סכמה ופרטי משתמש, שמפורטת בהמשך.
כללי אימות | |
---|---|
סכמה |
מזהי URI להפניה אוטומטית חייבים להשתמש בסכמת HTTPS, ולא ב-HTTP פשוט. מזהי URI של Localhost (כולל מזהי URI של כתובות IP של Localhost) פטורים מהכלל הזה. |
מארח |
מארחים לא יכולים להיות כתובות IP גולמיות. כתובות IP של מארח מקומי פטורות מהכלל הזה. |
דומיין |
“googleusercontent.com” .goo.gl ), אלא אם
הדומיין הוא בבעלות האפליקציה. בנוסף, אם אפליקציה שיש לה דומיין מקצר בוחרת
הפניה אוטומטית לדומיין הזה, ה-URI להפניה אוטומטית חייב להכיל
“/google-callback/” בנתיב או מסתיים ב-
“/google-callback” . |
פרטי משתמשים |
מזהי URI להפניה אוטומטית לא יכולים להכיל את רכיב המשנה userinfo. |
נתיב |
מזהי URI של הפניות אוטומטיות לא יכולים להכיל מעבר נתיב (נקרא גם 'מעקב לאחור של ספרייה'),
שמיוצג על ידי |
שאילתה |
מזהי URI להפניה אוטומטית לא יכולים להכיל הפניות אוטומטיות פתוחות. |
מקטע |
מזהי URI של הפניות אוטומטיות לא יכולים להכיל את רכיב המקטע. |
דמויות |
מזהי URI של הפניות לא יכולים להכיל תווים מסוימים, כולל:
|
הרשאה מצטברת
בפרוטוקול OAuth 2.0, האפליקציה מבקשת הרשאה לגשת למשאבים, אשר מזוהים באמצעות היקפים. כשחוויית המשתמש היא השיטה המומלצת ביותר היא לבקש הרשאה את המשאבים בזמן שאתם צריכים אותם. כדי להפעיל את השיטה הזו, שרת ההרשאות של Google תומך בהרשאה מצטברת. התכונה הזו מאפשרת לבקש היקפי הרשאות לפי הצורך, וגם אם המשתמש מעניק הרשאה להיקף החדש, מחזיר קוד הרשאה באסימון שמכיל את כל היקפי ההרשאות שהמשתמש העניק לפרויקט.
לדוגמה, ייתכן שלאפליקציה שמאפשרת לאנשים לדגום טראקים של מוזיקה וליצור מיקסים יידרשו מעט מאוד בזמן הכניסה לחשבון, אולי לא יותר מאשר השם של האדם שנכנס. אבל, לפעמים כדי לשמור מיקס שהסתיים, נדרשת גישה ל-Google Drive. רוב האנשים יראו את זה באופן טבעי אם הם התבקשו לגשת ל-Google Drive שלהם רק בזמן שהאפליקציה היה צורך בכך.
במקרה כזה, בזמן הכניסה האפליקציה עשויה לבקש את openid
וגם
profile
היקפי הרשאות לביצוע כניסה בסיסית, ומאוחר יותר יבקשו את
היקף הרשאות אחד (https://www.googleapis.com/auth/drive.file
) בזמן הבקשה הראשונה לשמירה של
מיקס.
כדי להטמיע הרשאה מצטברת, צריך להשלים את התהליך הרגיל של בקשת גישה אבל יש לוודא שבקשת ההרשאה כוללת היקפים שניתנו בעבר. הזה מאפשרת לאפליקציה להימנע מניהול של אסימוני גישה מרובים.
הכללים הבאים חלים על אסימון גישה שמתקבל מהרשאה מצטברת:
- ניתן להשתמש באסימון כדי לגשת למשאבים שתואמים לכל אחד מהיקפי ההרשאות שהופעלו הרשאה משולבת חדשה.
- כשמשתמשים באסימון הרענון עבור ההרשאה המשולבת כדי לקבל אסימון גישה,
אסימון הגישה מייצג את ההרשאה המשולבת וניתן להשתמש בו
scope
ערכים כלולים בתשובה. - ההרשאה המשולבת כוללת את כל היקפי ההרשאות שהמשתמש העניק לפרויקט ה-API, אפילו אם בקשות המענקים נשלחו מלקוחות שונים. לדוגמה, אם משתמש עם גישה אל היקף אחד באמצעות לקוח שולחן העבודה של אפליקציה, ואז העניק היקף אחר לאותו באמצעות לקוח לנייד, ההרשאה המשולבת תכלול את שני ההיקפים.
- אם תבטלו אסימון שמייצג הרשאה משולבת, תהיה לכם גישה לכל הפריטים האלה היקפי ההרשאות של ההרשאה בשם המשתמש המשויך מבוטלים בו-זמנית.
דוגמאות הקוד הספציפיות לשפה בשלב 1: הגדרת הרשאה פרמטרים ואת כתובת האתר להפניה מחדש מסוג HTTP/REST בשלב 2: הפניות אוטומטיות לשרת OAuth 2.0 של Google עושות שימוש בהרשאה מצטברת. דוגמאות הקוד שבהמשך יוצג גם הקוד שצריך להוסיף כדי להשתמש בהרשאה מצטברת.
PHP
$client->setIncludeGrantedScopes(true);
Python
ב-Python, מגדירים את הארגומנט include_granted_scopes
של מילת המפתח ל-true
לוודא שבקשת ההרשאה כוללת היקפי הרשאות שניתנו בעבר. ייתכן מאוד
include_granted_scopes
לא יהיה הארגומנט היחיד של מילת המפתח שתגדירו, כי
אפשר לראות בדוגמה שלמטה.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Ruby
auth_client.update!( :additional_parameters => {"include_granted_scopes" => "true"} )
Node.js
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
HTTP/REST
GET https://accounts.google.com/o/oauth2/v2/auth? client_id=your_client_id& response_type=code& state=state_parameter_passthrough_value& scope=https%3A//www.googleapis.com/auth/drive.file& redirect_uri=https%3A//oauth2.example.com/code& prompt=consent& include_granted_scopes=true
רענון אסימון גישה (גישה אופליין)
התוקף של אסימוני הגישה פג מדי פעם והם הופכים לפרטי כניסה לא חוקיים לבקשת API קשורה. שלך יכול לרענן אסימון גישה בלי לבקש הרשאה מהמשתמש (גם כשהמשתמש לא קיים) אם ביקשת גישה אופליין להיקפי ההרשאות שמשויכים לאסימון.
- אם משתמשים בספריית לקוח של Google API, אובייקט הלקוח עובר רענון את אסימון הגישה לפי הצורך, כל עוד מגדירים את האובייקט לגישה אופליין.
- אם לא משתמשים בספריית לקוח, צריך להגדיר את ה-HTTP
access_type
של השאילתה ל-offline
כאשר מתבצעת הפניה אוטומטית של המשתמש אל שרת OAuth 2.0 של Google. במקרה כזה, שרת ההרשאות של Google מחזיר אסימון רענון בעת החלפת הרשאה לאסימון גישה. לאחר מכן, אם התוקף של אסימון הגישה יפוג (או בכל זמן אחר), יכול להשתמש באסימון רענון כדי לקבל אסימון גישה חדש.
בקשה לגישה אופליין היא דרישה לכל אפליקציה שזקוקה לגישה
API כשהמשתמש לא נמצא. לדוגמה, אפליקציה שמבצעת שירותי גיבוי או
מבצע פעולות בזמנים שנקבעו מראש, צריך להיות מסוגל לרענן את אסימון הגישה שלו כאשר
המשתמש לא קיים. סגנון ברירת המחדל של הגישה נקרא online
.
אפליקציות אינטרנט בצד השרת, אפליקציות מותקנות ומכשירים מקבלים אסימוני רענון בתהליך ההרשאה. בדרך כלל לא משתמשים באסימוני רענון בצד הלקוח אפליקציות אינטרנט (JavaScript).
PHP
אם האפליקציה שלכם צריכה גישה אופליין ל-Google API, צריך להגדיר את סוג הגישה של לקוח ה-API כך:
offline
:
$client->setAccessType("offline");
אחרי שמשתמש מעניק גישה אופליין להיקפים המבוקשים, אפשר להמשיך להשתמש ב-API כדי לגשת ל-Google APIs בשם המשתמש כשהוא לא מחובר לאינטרנט. אובייקט הלקוח ירענן את אסימון הגישה לפי הצורך.
Python
ב-Python, צריך להגדיר את הארגומנט access_type
של מילת המפתח ל-offline
כדי לוודא
תהיה לך אפשרות לרענן את אסימון הגישה בלי לבקש שוב את הבקשה למשתמש
הרשאה. ייתכן מאוד ש-access_type
לא תהיה מילת המפתח היחידה
שהגדרתם, כפי שאפשר לראות בדוגמה הבאה.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
אחרי שמשתמש מעניק גישה אופליין להיקפים המבוקשים, אפשר להמשיך להשתמש ב-API כדי לגשת ל-Google APIs בשם המשתמש כשהוא לא מחובר לאינטרנט. אובייקט הלקוח ירענן את אסימון הגישה לפי הצורך.
Ruby
אם האפליקציה שלכם צריכה גישה אופליין ל-Google API, צריך להגדיר את סוג הגישה של לקוח ה-API כך:
offline
:
auth_client.update!( :additional_parameters => {"access_type" => "offline"} )
אחרי שמשתמש מעניק גישה אופליין להיקפים המבוקשים, אפשר להמשיך להשתמש ב-API כדי לגשת ל-Google APIs בשם המשתמש כשהוא לא מחובר לאינטרנט. אובייקט הלקוח ירענן את אסימון הגישה לפי הצורך.
Node.js
אם האפליקציה שלכם צריכה גישה אופליין ל-Google API, צריך להגדיר את סוג הגישה של לקוח ה-API כך:
offline
:
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
אחרי שמשתמש מעניק גישה אופליין להיקפים המבוקשים, אפשר להמשיך להשתמש ב-API כדי לגשת ל-Google APIs בשם המשתמש כשהוא לא מחובר לאינטרנט. אובייקט הלקוח ירענן את אסימון הגישה לפי הצורך.
התוקף של אסימוני הגישה פג. הספרייה הזו תשתמש באופן אוטומטי באסימון רענון כדי לקבל גישה חדשה אם התוקף שלו עומד לפוג. דרך קלה לוודא שתמיד שומרים את האסימונים האחרונים הוא להשתמש באירוע האסימונים:
oauth2Client.on('tokens', (tokens) => { if (tokens.refresh_token) { // store the refresh_token in your secure persistent database console.log(tokens.refresh_token); } console.log(tokens.access_token); });
אירוע האסימונים הזה מתרחש רק בהרשאה הראשונה, וצריך להגדיר את
access_type
אל offline
בהתקשרות לgenerateAuthUrl
כדי לקבל את אסימון הרענון. אם כבר הענקת לאפליקציה את הרשאות הבקשה
מבלי להגדיר את המגבלות המתאימות לקבלת אסימון רענון, יהיה עליך
מאשרים מחדש את האפליקציה לקבל אסימון רענון חדש.
כדי להגדיר את refresh_token
במועד מאוחר יותר, אפשר להשתמש בשיטה setCredentials
:
oauth2Client.setCredentials({ refresh_token: `STORED_REFRESH_TOKEN` });
אחרי שללקוח יש אסימון רענון, אסימוני הגישה יאספו וירעננו באופן אוטומטי בקריאה הבאה ל-API.
HTTP/REST
כדי לרענן אסימון גישה, האפליקציה שולחת כתובת URL מסוג HTTPS מסוג POST
לשרת האימות של Google (https://oauth2.googleapis.com/token
)
כוללת את הפרמטרים הבאים:
שדות | |
---|---|
client_id |
מזהה הלקוח שהתקבל מ- API Console. |
client_secret |
סוד הלקוח שהתקבל מ- API Console. |
grant_type |
בתור
מוגדר ב-
מפרט OAuth 2.0,
הערך בשדה הזה צריך להיות refresh_token . |
refresh_token |
אסימון הרענון שהוחזר מהמרת קוד ההרשאה. |
קטע הקוד הבא מציג בקשה לדוגמה:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=your_client_id& client_secret=your_client_secret& refresh_token=refresh_token& grant_type=refresh_token
שרת האסימון לא ביטל את הגישה שהוענקה לאפליקציה כל עוד המשתמש לא ביטל את הגישה מחזירה אובייקט JSON שמכיל אסימון גישה חדש. בקטע הקוד הבא מוצגת דוגמה תגובה:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "token_type": "Bearer" }
חשוב לשים לב שיש הגבלות על מספר אסימוני הרענון שיונפקו. מגבלה אחת לכל שילוב של לקוח/משתמש ושילוב נוסף לכל משתמש בכל הלקוחות. עליך לשמור אסימוני רענון באחסון לטווח ארוך ולהמשיך להשתמש בהם כל עוד הם בתוקף. אם הבקשה שלכם מבקשת יותר מדי אסימוני רענון, היא עלולה להגיע למגבלות האלה. במקרה כזה, אסימוני רענון ישנים יותר יפסיקו לפעול.
ביטול אסימון
במקרים מסוימים משתמש עשוי לבטל את הגישה שניתנה לאפליקציה. משתמש יכול לבטל את הגישה על ידי ביקור בכתובת הגדרות חשבון. לצפייה הסרה קטע הגישה של האתר או האפליקציה באתרים של צדדים שלישיים אפליקציות עם גישה לחשבון מסמך תמיכה של Google לקבלת מידע נוסף.
אפשר גם שאפליקציה יכולה לבטל באופן פרוגרמטי את הגישה שהוענקה לה. ביטול פרוגרמטי חשוב במקרים שבהם משתמש מבטל את ההרשמה ומסיר או משאבי ה-API הנדרשים על ידי אפליקציה השתנו באופן משמעותי. במילים אחרות, חלק מתהליך ההסרה יכול לכלול בקשת API כדי לוודא שההרשאות בעבר שהוענקו לאפליקציה יוסרו.
PHP
כדי לבטל אסימון באופן פרוגרמטי, קוראים לפונקציה revokeToken()
:
$client->revokeToken();
Python
כדי לבטל אסימון באופן פרוגרמטי, צריך לשלוח בקשה אל
https://oauth2.googleapis.com/revoke
שכולל את האסימון כפרמטר ומגדיר את
הכותרת Content-Type
:
requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'})
Ruby
כדי לבטל אסימון באופן פרוגרמטי, צריך לשלוח בקשת HTTP אל oauth2.revoke
נקודת קצה (endpoint):
uri = URI('https://oauth2.googleapis.com/revoke') response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
האסימון יכול להיות אסימון גישה או אסימון רענון. אם האסימון הוא אסימון גישה ויש לו אסימון רענון תואם, גם אסימון הרענון יבוטל.
אם הביטול יעובד בהצלחה, קוד הסטטוס של התשובה יהיה
200
עבור תנאים של שגיאה, מוחזר קוד הסטטוס 400
יחד עם
קוד שגיאה.
Node.js
כדי לבטל אסימון באופן פרוגרמטי, צריך לשלוח בקשת HTTPS POST אל /revoke
נקודת קצה (endpoint):
const https = require('https'); // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end();
פרמטר האסימון יכול להיות אסימון גישה או אסימון רענון. אם האסימון הוא אסימון גישה ויש לו אסימון רענון תואם, גם אסימון הרענון יבוטל.
אם הביטול יעובד בהצלחה, קוד הסטטוס של התשובה יהיה
200
עבור תנאים של שגיאה, מוחזר קוד הסטטוס 400
יחד עם
קוד שגיאה.
HTTP/REST
כדי לבטל אסימון באופן פרוגרמטי, האפליקציה שולחת בקשה ל-
https://oauth2.googleapis.com/revoke
והוא כולל את האסימון כפרמטר:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
האסימון יכול להיות אסימון גישה או אסימון רענון. אם האסימון הוא אסימון גישה ויש לו אסימון הרענון התואם, גם אסימון הרענון יבוטל.
אם הביטול בוצע בהצלחה, קוד סטטוס ה-HTTP של התשובה
200
במקרים של שגיאות, מוחזר קוד מצב HTTP 400
עם קוד שגיאה.
יישום הגנה על כל החשבונות
פעולה נוספת שצריך לבצע כדי להגן על המשתמשים משתמשים בחשבונות שונים הגנה על ידי שימוש בשירות ההגנה על כל החשבונות של Google. השירות הזה מאפשר לך הרשמה להתראות על פעולות שמשפיעות על אבטחת החשבון, שמספקות מידע לאפליקציה על שינויים משמעותיים בחשבון המשתמש. לאחר מכן תוכלו להשתמש במידע כדי לנקוט פעולה בהתאם האופן שבו אתם מחליטים להגיב לאירועים.
אלה כמה דוגמאות לסוגי האירועים שנשלחים לאפליקציה שלכם על ידי שירות ההגנה על כל החשבונות של Google:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
-
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
לצפייה הגנה על חשבונות משתמשים באמצעות הדף 'הגנה על כל החשבונות' כדי לקבל מידע נוסף על ההטמעה של הגנה על כל החשבונות ולרשימה המלאה של האירועים הזמינים.