המסמך הזה מסביר איך אפליקציות של שרת אינטרנט משתמשות בספריות לקוח של Google API או בנקודות קצה של OAuth 2.0 של Google כדי להטמיע הרשאת OAuth 2.0 כדי לגשת ל-YouTube Data API.
OAuth 2.0 מאפשר למשתמשים לשתף נתונים ספציפיים עם אפליקציה, תוך שמירה על הפרטיות של שמות המשתמשים, הסיסמאות ומידע אחר שלהם. לדוגמה, אפליקציה יכולה להשתמש ב-OAuth 2.0 כדי לקבל הרשאה להעלות סרטונים לערוץ YouTube של המשתמש.
התהליך הזה ב-OAuth 2.0 מיועד במיוחד להרשאה של משתמשים. הוא מיועד לאפליקציות שיכולות לאחסן מידע סודי ולשמור על מצב. אפליקציית שרת אינטרנט עם הרשאה מתאימה יכולה לגשת ל-API בזמן שהמשתמש מקיים אינטראקציה עם האפליקציה או אחרי שהוא יצא מהאפליקציה.
לעיתים קרובות, אפליקציות של שרתי אינטרנט משתמשות ב
חשבונות שירות כדי לאשר בקשות API, במיוחד כשהן קריאות לממשקי Cloud API לגשת לנתונים מבוססי-פרויקטים במקום לנתונים ספציפיים למשתמש. אפליקציות של שרתי אינטרנט יכולות להשתמש בחשבונות שירות בשילוב עם הרשאת משתמשים.
שימו לב ש-YouTube Data API תומך בתהליך של חשבון השירות רק לבעלי תוכן ב-YouTube שהם הבעלים והמנהלים של מספר ערוצי YouTube.
באופן ספציפי, בעלי תוכן יכולים להשתמש בחשבונות שירות כדי לשלוח קריאה ל-methods של ה-API שתומכות בפרמטר של הבקשה onBehalfOfContentOwner
.
ספריות לקוח
בדוגמאות הספציפיות לשפה בדף הזה נעשה שימוש בספריות הלקוח של 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.
- בדף ספרייה אפשר למצוא את ממשק YouTube Data API ולהפעיל אותו. צריך לחפש ממשקי API אחרים שהאפליקציה תשתמש בהם ולהפעיל גם אותם.
יצירת פרטי כניסה להרשאה
כל אפליקציה שמשתמשת ב-OAuth 2.0 כדי לגשת ל-Google APIs צריכה להיות עם פרטי כניסה להרשאה שמזהים את האפליקציה לשרת OAuth 2.0 של Google. בשלבים הבאים מוסבר איך ליצור את פרטי הכניסה לפרויקט. לאחר מכן האפליקציות יכולות להשתמש בפרטי הכניסה כדי לגשת לממשקי ה-API שהפעלתם בפרויקט הזה.
- Go to the Credentials page.
- לוחצים על Create credentials > מזהה לקוח OAuth.
- בוחרים בסוג האפליקציה Web application.
- ממלאים את הטופס ולוחצים על יצירה. באפליקציות שמשתמשות בשפות וב-frameworks כמו 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, מומלץ לזהות את היקפי ההרשאות שהאפליקציה צריכה הרשאה כדי לגשת אליהן.
בנוסף, מומלץ שהאפליקציה תבקש גישה להיקפי ההרשאות באמצעות תהליך של הרשאה מצטברת, שבו האפליקציה מבקשת גישה לנתוני המשתמש בהקשר המתאים. השיטה המומלצת הזו עוזרת למשתמשים להבין בקלות למה האפליקציה מבקשת את הגישה שהיא מבקשת.
ממשק YouTube Data API v3 משתמש בהיקפים הבאים:
טווחים | |
---|---|
https://www.googleapis.com/auth/youtube | ניהול חשבון YouTube שלך |
https://www.googleapis.com/auth/youtube.channel-memberships.creator | הצגת רשימה מעודכנת של החברים הפעילים במועדון החברים של הערוץ, הרמה הנוכחית שלהם והתאריך שבו הם הצטרפו למועדון |
https://www.googleapis.com/auth/youtube.force-ssl | הצגה, עריכה ומחיקה לצמיתות של סרטונים, דירוגים, תגובות וכתוביות ב-YouTube |
https://www.googleapis.com/auth/youtube.readonly | הצגת חשבון YouTube שלך |
https://www.googleapis.com/auth/youtube.upload | ניהול הסרטונים שלך ב-YouTube |
https://www.googleapis.com/auth/youtubepartner | הצגה וניהול של הנכסים והתכנים הקשורים שלך ב-YouTube |
https://www.googleapis.com/auth/youtubepartner-channel-audit | הצגת מידע פרטי של ערוץ YouTube שלך הרלוונטי בתהליך הביקורת של שותף YouTube. |
המסמך היקפי 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.
קבלת אסימוני גישה מסוג 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
.
לדוגמה, הקוד הזה מבקש גישה אופליין כדי לנהל חשבון YouTube של משתמש:
$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_YOUTUBE::YOUTUBE_FORCE_SSL); // Required, call the setRedirectUri function to specify a valid redirect URI for the // provided client_id $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // Recommended, offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType('offline'); // Recommended, call the setState function. Using a state value can increase your assurance that // an incoming connection is the result of an authentication request. $client->setState($sample_passthrough_value); // Optional, if your application knows which user is trying to authenticate, it can use this // parameter to provide a hint to the Google Authentication Server. $client->setLoginHint('hint@example.com'); // Optional, call the setPrompt function to set "consent" will prompt the user for consent $client->setPrompt('consent'); // Optional, call the setIncludeGrantedScopes function with true to enable incremental // authorization $client->setIncludeGrantedScopes(true);
Python
קטע הקוד הבא משתמש במודול google-auth-oauthlib.flow
כדי ליצור את בקשת ההרשאה.
הקוד יוצר אובייקט Flow
שמזהה את האפליקציה באמצעות מידע מהקובץ client_secret.json שהורדתם אחרי שיצרתם פרטי כניסה להרשאה. האובייקט הזה גם מזהה את היקפי ההרשאות שהאפליקציה מבקשת הרשאה לגשת אליהן, ואת כתובת ה-URL של נקודת הקצה לאימות של האפליקציה. הגישה הזו תטפל בתגובה משרת OAuth 2.0 של Google. לבסוף, הקוד מגדיר את הפרמטרים האופציונליים access_type
ו-include_granted_scopes
.
לדוגמה, הקוד הזה מבקש גישה אופליין כדי לנהל חשבון YouTube של משתמש:
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/youtube.force-ssl']) # Required, indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. flow.redirect_uri = 'https://www.example.com/oauth2callback' # Generate URL for request to Google's OAuth 2.0 server. # Use kwargs to set optional request parameters. authorization_url, state = flow.authorization_url( # Recommended, enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Optional, enable incremental authorization. Recommended as a best practice. include_granted_scopes='true', # Optional, if your application knows which user is trying to authenticate, it can use this # parameter to provide a hint to the Google Authentication Server. login_hint='hint@example.com', # Optional, set prompt to 'consent' will prompt the user for consent prompt='consent')
Ruby
משתמשים בקובץ client_secrets.json שיצרתם כדי להגדיר אובייקט לקוח באפליקציה. כשמגדירים אובייקט לקוח, צריך לציין את היקפי ההרשאות שהאפליקציה צריכה לגשת אליהן, יחד עם כתובת ה-URL של נקודת הקצה לאימות של האפליקציה, שתטפל בתגובה משרת OAuth 2.0.
לדוגמה, הקוד הזה מבקש גישה אופליין כדי לנהל חשבון YouTube של משתמש:
require 'google/apis/youtube_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/youtube.force-ssl' 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
. ניתן לגשת לנקודת הקצה הזו רק באמצעות 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 מציגה למשתמש. היקפי הרשאות מאפשרים לאפליקציה לבקש גישה רק למשאבים שנחוצים לה, וגם מאפשרים למשתמשים לשלוט בכמות הגישה שהם מעניקים לאפליקציה. לכן, יש קשר הפוך בין מספר היקפי ההרשאות שנדרשים לבין הסבירות לקבלת הסכמה מהמשתמשים. ממשק YouTube Data API v3 משתמש בהיקפים הבאים:
המסמך היקפי API של OAuth 2.0 כולל רשימה מלאה של היקפים שבהם תוכלו להשתמש כדי לגשת ל-Google APIs. כשהדבר אפשרי, מומלץ שהאפליקציה תבקש גישה להיקפי הרשאות של הרשאות בהקשר. כשמבקשים גישה לנתוני המשתמשים בהקשר מסוים, באמצעות הרשאה מצטברת, קל יותר למשתמשים להבין למה האפליקציה מבקשת את הגישה אליה. |
||||||||||||||||
access_type |
המלצות
מציינת אם האפליקציה יכולה לרענן את אסימוני הגישה כשהמשתמש לא נמצא בדפדפן. ערכי הפרמטרים החוקיים הם מגדירים את הערך ל- |
||||||||||||||||
state |
המלצות
מציינת כל ערך מחרוזת שבו האפליקציה משתמשת כדי לשמור על המצב בין
בקשת ההרשאה לבין התגובה של שרת ההרשאות.
השרת מחזיר את הערך המדויק שאתם שולחים בתור צמד אפשר להשתמש בפרמטר הזה לכמה מטרות, כמו הפניה של המשתמש
למשאב הנכון באפליקציה, שליחת צפנים חד-פעמיים (nonce) וצמצום זיוף בקשות בין אתרים. אפשר לנחש את |
||||||||||||||||
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
-
כדי לבקש גישה משרת OAuth 2.0 של Google, צריך להשתמש בכתובת ה-URL שנוצרה
authorizationUrl
מהשיטה שלב 1generateAuthUrl
. -
מפנים את המשתמש לכתובת
authorizationUrl
.res.redirect(authorizationUrl);
HTTP/REST
Sample redirect to Google's authorization server
The sample URL below requests offline access
(access_type=offline
) to a scope that permits access to view
the user's YouTube account. It uses incremental authorization to ensure that
the new access token covers any scopes to which the user previously granted
the application access. The URL also sets values for the required
redirect_uri
, response_type
, and
client_id
parameters as well as for the state
parameter. The URL contains line breaks and spaces for readability.
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
access_type=offline&
include_granted_scopes=true&
state=state_parameter_passthrough_value&
redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
response_type=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 Workspace, אין אפשרות לתת הרשאה להיקף הרשאות אחד או יותר בחשבון Google. במאמר העזרה לאדמינים ב-Google Workspace מוסבר איך לקבוע לאילו אפליקציות של צד שלישי ואפליקציות פנימיות תהיה גישה לנתונים של Google Workspace, למידע נוסף על האופן שבו האדמין יכול להגביל את הגישה לכל ההיקפים או להיקפים הרגישים והמוגבלים, עד שתוענק גישה מפורשת למזהה הלקוח שלכם ב-OAuth.
disallowed_useragent
נקודת הקצה (endpoint) של ההרשאה מוצגת בתוך סוכן משתמש מוטמע שאסור לפי מדיניות 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 פותחת קישור כללי לאינטרנט
בסוכן משתמש מוטמע, כשמשתמש יעבור מהאתר לנקודת הקצה (endpoint) של הרשאת 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%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly& access_type=offline& include_granted_scopes=true& state=state_parameter_passthrough_value& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& response_type=code& client_id=client_id
אחרי שתשלימו את התהליך ב-OAuth 2.0, תופנו אל
http://localhost/oauth2callback
, שככל הנראה תניב שגיאת 404 NOT FOUND
, אלא אם המחשב המקומי שלכם יציג קובץ בכתובת הזו. בשלב הבא מקבלים פרטים נוספים על המידע שמוחזר ב-URI כשהמשתמש מופנה בחזרה לאפליקציה.
שלב 5: החלפת קוד ההרשאה באסימוני רענון וגישה
אחרי ששרת האינטרנט מקבל את קוד ההרשאה, הוא יכול להחליף את קוד ההרשאה באסימון גישה.
PHP
כדי להחליף קוד הרשאה באסימון גישה, משתמשים בשיטה authenticate
:
$client->authenticate($_GET['code']);
אפשר לאחזר את אסימון הגישה באמצעות ה-method getAccessToken
:
$access_token = $client->getAccessToken();
Python
בדף הקריאה החוזרת, משתמשים בספרייה google-auth
כדי לאמת את התגובה של שרת ההרשאות. אחרי זה, משתמשים ב-method 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/youtube.force-ssl'], 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
כדי לאמת את התגובה של שרת ההרשאות. משתמשים ב-method authorizer.handle_auth_callback_deferred
כדי לשמור את קוד ההרשאה ולהפנות חזרה לכתובת ה-URL שביקשה הרשאה במקור. כך ניתן למנוע את החלפת הקוד על ידי הסתרה זמנית של התוצאות בסשן של המשתמש.
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url
Node.js
כדי להחליף קוד הרשאה באסימון גישה, משתמשים בשיטה getToken
:
const url = require('url'); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); });
HTTP/REST
כדי להחליף קוד הרשאה באסימון גישה, מפעילים את נקודת הקצה https://oauth2.googleapis.com/token
ומגדירים את הפרמטרים הבאים:
שדות | |
---|---|
client_id |
מזהה הלקוח שהתקבל מ- API Console Credentials page. |
client_secret |
סוד הלקוח שהתקבל מ- API Console Credentials page. |
code |
קוד ההרשאה שהוחזר מהבקשה הראשונית. |
grant_type |
כפי שמוגדר במפרט של OAuth 2.0, הערך בשדה הזה צריך להיות authorization_code . |
redirect_uri |
אחד ממזהי ה-URI להפניה אוטומטית שרשומים לפרויקט שלכם ב- API Console
Credentials page של client_id הנתון. |
קטע הקוד הבא מציג בקשה לדוגמה:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=https%3A//oauth2.example.com/code& grant_type=authorization_code
Google מגיבה לבקשה הזו על ידי החזרת אובייקט JSON שמכיל אסימון גישה לטווח קצר
ואסימון רענון.
שימו לב שאסימון הרענון מוחזר רק אם האפליקציה מגדירה את הפרמטר access_type
כ-offline
בבקשה הראשונית לשרת ההרשאות של Google.
התשובה תכיל את השדות הבאים:
שדות | |
---|---|
access_token |
האסימון שהאפליקציה שלכם שולחת כדי לאשר בקשת Google API. |
expires_in |
משך החיים שנותר לאסימון הגישה, בשניות. |
refresh_token |
אסימון שאפשר להשתמש בו כדי לקבל אסימון גישה חדש. אסימוני הרענון תקפים עד
שהמשתמש מבטל את הגישה.
שוב, השדה הזה יופיע בתשובה הזו רק אם מגדירים את הפרמטר access_type
כ-offline בבקשה הראשונית שנשלחת לשרת ההרשאות של Google.
|
scope |
היקפי הגישה שהוענקו על ידי access_token , מוצגים כרשימה של מחרוזות תלויות-רישיות שמופרדות ברווחים. |
token_type |
סוג האסימון המוחזר. בשלב הזה, הערך בשדה הזה תמיד מוגדר כ-Bearer . |
בקטע הקוד הבא מוצגת תגובה לדוגמה:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/youtube.force-ssl", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
שגיאות
כשמחליפים את קוד ההרשאה באסימון גישה, יכול להיות שתופיע השגיאה הבאה במקום התגובה הצפויה. קודי שגיאות נפוצים והצעות לפתרונות מפורטים בהמשך.
invalid_grant
קוד ההרשאה שסופק אינו חוקי או בפורמט שגוי. כדי לבקש קוד חדש, צריך להפעיל מחדש את תהליך OAuth ולבקש מהמשתמש שוב הסכמה.
קריאה ל-Google APIs
PHP
משתמשים באסימון הגישה כדי לקרוא ל-Google APIs. לשם כך מבצעים את השלבים הבאים:
- אם צריך להחיל אסימון גישה על אובייקט
Google\Client
חדש – לדוגמה, אם אחסנתם את אסימון הגישה בסשן של משתמש – משתמשים ב-methodsetAccessToken
:$client->setAccessToken($access_token);
- יוצרים אובייקט שירות ל-API שאליו רוצים לקרוא. כדי ליצור אובייקט שירות, מספקים ל-constructor של אובייקט השירות אובייקט
Google\Client
מורשה של ה-API שרוצים לקרוא אליו. לדוגמה, כדי לשלוח קריאה ל-YouTube Data API:$youtube = new Google_Service_YouTube($client);
- שולחים בקשות לשירות ה-API באמצעות הממשק של אובייקט השירות.
לדוגמה, כדי לאחזר נתונים על ערוץ YouTube של המשתמש המורשה:
$channel = $youtube->channels->listChannels('snippet', array('mine' => $mine));
Python
אחרי קבלת אסימון גישה, האפליקציה יכולה להשתמש באסימון הזה כדי לאשר בקשות API בשם חשבון משתמש או חשבון שירות נתונים. משתמשים בפרטי הכניסה להרשאה הספציפית למשתמש כדי ליצור אובייקט שירות ל-API שאליו רוצים לקרוא, ולאחר מכן משתמשים באובייקט כדי לשלוח בקשות API מורשות.
- יוצרים אובייקט שירות ל-API שאליו רוצים לקרוא. כדי ליצור אובייקט שירות, שולחים קריאה ל-method
build
של הספרייהgoogleapiclient.discovery
עם השם והגרסה של ה-API ועם פרטי הכניסה של המשתמש: לדוגמה, כדי להפעיל את גרסה 3 של YouTube Data API:from googleapiclient.discovery import build youtube = build('youtube', 'v3', credentials=credentials)
- שולחים בקשות לשירות ה-API באמצעות הממשק של אובייקט השירות.
לדוגמה, כדי לאחזר נתונים על ערוץ YouTube של המשתמש המורשה:
channel = youtube.channels().list(mine=True, part='snippet').execute()
Ruby
אחרי קבלת אסימון גישה, האפליקציה שלך יכולה להשתמש באסימון הזה כדי לשלוח בקשות API בשם חשבון משתמש או חשבון שירות מסוימים. משתמשים בפרטי הכניסה להרשאה הספציפית למשתמש כדי ליצור אובייקט שירות ל-API שאליו רוצים לקרוא, ולאחר מכן משתמשים באובייקט כדי לשלוח בקשות API מורשות.
- יוצרים אובייקט שירות ל-API שאליו רוצים לקרוא.
לדוגמה, כדי להפעיל את גרסה 3 של YouTube Data API:
youtube = Google::Apis::YoutubeV3::YouTubeService.new
- מגדירים את פרטי הכניסה בשירות:
youtube.authorization = credentials
- שולחים בקשות לשירות ה-API באמצעות הממשק של אובייקט השירות.
לדוגמה, כדי לאחזר נתונים על ערוץ YouTube של המשתמש המורשה:
channel = youtube.list_channels(part, :mine => mine)
לחלופין, אפשר לתת הרשאה לכל שיטה בנפרד, באמצעות ציון
הפרמטר options
ל-method:
channel = youtube.list_channels(part, :mine => mine, options: { authorization: auth_client })
Node.js
אחרי קבלת אסימון גישה והגדרתו לאובייקט OAuth2
, משתמשים באובייקט כדי לקרוא ל-Google APIs. האפליקציה שלך יכולה להשתמש באסימון הזה כדי לאשר בקשות API בשם
חשבון משתמש או חשבון שירות נתונים. יוצרים אובייקט שירות ל-API שאליו רוצים לקרוא.
const { google } = require('googleapis'); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } });
HTTP/REST
אחרי שהאפליקציה מקבלת אסימון גישה, אפשר להשתמש באסימון כדי לבצע קריאות ל-Google API מטעם
חשבון משתמש נתון, אם הוענקו היקפי הגישה שנדרשים על ידי ה-API. כדי לעשות את זה צריך לכלול את אסימון הגישה בבקשה ל-API, על ידי הכללת פרמטר של שאילתה access_token
או ערך Bearer
של כותרת ה-HTTP של Authorization
. כשזה אפשרי, עדיף להשתמש בכותרת ה-HTTP כי מחרוזות השאילתה בדרך כלל גלויות ביומני השרת. ברוב המקרים אפשר להשתמש בספריית לקוח כדי להגדיר את הקריאות ל-Google APIs (למשל, כששולחים קריאה ל-YouTube Data API).
שימו לב ש-YouTube Data API תומך בחשבונות שירות רק לבעלי תוכן ב-YouTube, שבבעלותם ובניהולם של מספר ערוצי YouTube, כמו לייבלים ואולפני סרטים.
תוכלו לנסות את כל ממשקי ה-API של Google ולצפות בהיקפים שלהם ב-OAuth 2.0 Playground.
דוגמאות ל-HTTP GET
קריאה לנקודת הקצה (
youtube.channels
) (YouTube Data API) באמצעות כותרת ה-HTTP Authorization: Bearer
עשויה להיראות כך. שימו לב שתצטרכו לציין אסימון גישה משלכם:
GET /youtube/v3/channels?part=snippet&mine=true HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
זוהי קריאה לאותו API בשביל המשתמש המאומת באמצעות הפרמטר access_token
של מחרוזת השאילתה:
GET https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true
curl
דוגמאות
אפשר לבדוק את הפקודות האלה באמצעות אפליקציית שורת הפקודה curl
. הנה דוגמה שמשתמשת באפשרות של כותרת ה-HTTP (האפשרות המועדפת):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true
לחלופין, אפשרות הפרמטר של מחרוזת השאילתה:
curl https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true
דוגמה מלאה
הדוגמה הבאה מדפיסה אובייקט בפורמט JSON שמציג מידע על ערוץ YouTube של המשתמש, לאחר שהמשתמש מבצע אימות ומאשר לאפליקציה לנהל את חשבון YouTube של המשתמש.
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_YOUTUBE::YOUTUBE_FORCE_SSL); if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); $youtube = new Google_Service_YouTube($client); $channel = $youtube->channels->listChannels('snippet', array('mine' => $mine)); echo json_encode($channel); } 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_YOUTUBE::YOUTUBE_FORCE_SSL); 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/youtube.force-ssl'] API_SERVICE_NAME = 'youtube' API_VERSION = 'v3' 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']) youtube = googleapiclient.discovery.build( API_SERVICE_NAME, API_VERSION, credentials=credentials) channel = youtube.channels().list(mine=True, part='snippet').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(**channel) @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/youtube_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 youtube = Google::Apis::YoutubeV3::YouTubeService.new channel = youtube.list_channels(part, :mine => mine, options: { authorization: auth_client }) "<pre>#{JSON.pretty_generate(channel.to_h)}</pre>" end get '/oauth2callback' do target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url end
Node.js
כדי להריץ את הדוגמה הזו:
-
בשדה API Console, מוסיפים את כתובת ה-URL של המכונה המקומית לרשימת כתובות ה-URL להפניה אוטומטית, למשל
http://localhost
. - צריך לוודא שמותקנים LTS, LTS פעילים או גרסה נוכחית של Node.js לצורך תחזוקה.
-
יוצרים ספרייה חדשה ומשנים אליה. לדוגמה:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Install the
Google API Client
Library
for Node.js using npm:
npm install googleapis
-
יוצרים את הקבצים
main.js
עם התוכן שלמטה. -
מריצים את הדוגמה:
node .\main.js
main.js
const http = require('http'); const https = require('https'); const url = require('url'); const { google } = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. * To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Drive activity. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly' ]; /* Global variable that stores user credential in this code example. * ACTION ITEM for developers: * Store user's refresh token in your data store if * incorporating this code into your real app. * For more information on handling refresh tokens, * see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens */ let userCredential = null; async function main() { const app = express(); app.use(session({ secret: 'your_secure_secret_key', // Replace with a strong secret resave: false, saveUninitialized: false, })); // Example on redirecting user to Google's OAuth 2.0 server. app.get('/', async (req, res) => { // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // Generate a url that asks permissions for the Drive activity scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true, // Include the state parameter to reduce the risk of CSRF attacks. state: state }); res.redirect(authorizationUrl); }); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { // Handle the OAuth 2.0 server response let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); /** Save credential to the global variable in case access token was refreshed. * ACTION ITEM: In a production app, you likely want to save the refresh token * in a secure persistent database instead. */ userCredential = tokens; // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } }); } }); // Example on revoking a token app.get('/revoke', async (req, res) => { // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end(); }); const server = http.createServer(app); server.listen(80); } main().catch(console.error);
HTTP/REST
הדוגמה הזו של Python משתמשת ב-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/youtube.force-ssl' 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/youtube/v3/channels/list' 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.
כללי אימות | |
---|---|
סכמה |
מזהי URI להפניה אוטומטית חייבים להשתמש בסכמת HTTPS, ולא ב-HTTP פשוט. מזהי URI של מארח מקומי (כולל מזהי 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 שלהם.
במקרה כזה, בזמן הכניסה, יכול להיות שהאפליקציה לא תצטרך גישה להיקפים כלשהם או לא תבקש גישה אליהם. עם זאת, אם המשתמש ניסה לסווג סרטון, להוסיף סרטון לפלייליסט או לבצע פעולה אחרת ב-YouTube, האפליקציה תוכל לבקש גישה להיקף ההרשאות https://www.googleapis.com/auth/youtube.force-ssl
.
באופן דומה, האפליקציה יכולה לבקש גישה להיקף https://www.googleapis.com/auth/calendar
אם המשתמש ניסה להוסיף אירוע ביומן.
כדי להטמיע הרשאה מצטברת, צריך לבצע את התהליך הרגיל של בקשת אסימון גישה, אבל לוודא שבקשת ההרשאה כוללת היקפי הרשאות שניתנו בעבר. כך האפליקציה לא צריכה לנהל אסימוני גישה מרובים.
הכללים הבאים חלים על אסימון גישה שמתקבל מהרשאה מצטברת:
- אפשר להשתמש באסימון כדי לגשת למשאבים שמתאימים לכל אחד מהיקפי ההרשאות שהועברו להרשאה המשולבת החדשה.
- כשמשתמשים באסימון הרענון עבור ההרשאה המשולבת כדי לקבל אסימון גישה, אסימון הגישה מייצג את ההרשאה המשולבת ואפשר להשתמש בו לכל אחד מהערכים של
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
בדוגמה הזו, אפליקציית הקריאה מבקשת גישה כדי לאחזר את נתוני YouTube Analytics של המשתמש, בנוסף לכל גישה אחרת שהמשתמש כבר העניק לאפליקציה.
GET https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly& access_type=offline& state=security_token%3D138rk%3Btarget_url%3Dhttp...index& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& response_type=code& client_id=client_id& include_granted_scopes=true
Refreshing an access token (offline access)
Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.
- If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
- If you are not using a client library, you need to set the
access_type
HTTP query parameter tooffline
when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.
Requesting offline access is a requirement for any application that needs to access a Google
API when the user is not present. For example, an app that performs backup services or
executes actions at predetermined times needs to be able to refresh its access token when the
user is not present. The default style of access is called online
.
Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.
PHP
If your application needs offline access to a Google API, set the API client's access type to
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
כדי לרענן אסימון גישה, האפליקציה שולחת בקשת POST
מסוג HTTPS לשרת ההרשאות של Google (https://oauth2.googleapis.com/token
) שכוללת את הפרמטרים הבאים:
שדות | |
---|---|
client_id |
מזהה הלקוח שהתקבל מ- API Console. |
client_secret |
סוד הלקוח שהתקבל מ- API Console. |
grant_type |
כפי שמוגדר במפרט של OAuth 2.0, הערך בשדה הזה צריך להיות refresh_token . |
refresh_token |
אסימון הרענון שהוחזר מהמרת קוד ההרשאה. |
קטע הקוד הבא מציג בקשה לדוגמה:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=your_client_id& client_secret=your_client_secret& refresh_token=refresh_token& grant_type=refresh_token
כל עוד המשתמש לא ביטל את הגישה שהוענקה לאפליקציה, שרת האסימונים מחזיר אובייקט JSON שמכיל אסימון גישה חדש. בקטע הקוד הבא מוצגת תגובה לדוגמה:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "token_type": "Bearer" }
חשוב לשים לב שיש הגבלות על מספר אסימוני הרענון שיונפקו – מגבלה אחת לכל שילוב של לקוח/משתמש ומגבלה נוספת לכל משתמש בכל הלקוחות. צריך לשמור אסימוני רענון באחסון לטווח ארוך ולהמשיך להשתמש בהם כל עוד הם בתוקף. אם האפליקציה מבקשת יותר מדי אסימוני רענון, היא עלולה להגיע למגבלות האלה, ובמקרה כזה אסימוני רענון ישנים יותר יפסיקו לפעול.
ביטול אסימון
במקרים מסוימים משתמש עשוי לבטל את הגישה שניתנה לאפליקציה. המשתמש יכול לבטל את הגישה דרך הגדרות החשבון. למידע נוסף, אפשר לעיין בקטע התמיכה לגבי הסרת הגישה של אתר או אפליקציה מאתרים ואפליקציות של צד שלישי שיש להם גישה לחשבון.
אפשר גם שאפליקציה יכולה לבטל באופן פרוגרמטי את הגישה שהוענקה לה. ביטול פרוגרמטי חשוב במקרים שבהם משתמש מבטל את ההרשמה או מסיר אפליקציה, או שחל שינוי משמעותי במשאבי ה-API שנדרשים על ידי האפליקציה. כלומר, חלק מתהליך ההסרה יכול לכלול בקשת API, כדי להבטיח שההרשאות שניתנו בעבר לאפליקציה יוסרו.
PHP
כדי לבטל אסימון באופן פרוגרמטי, קוראים לפונקציה revokeToken()
:
$client->revokeToken();
Python
כדי לבטל אסימון באופן פרוגרמטי, שולחים בקשה
ל-https://oauth2.googleapis.com/revoke
שכוללת את האסימון כפרמטר ומגדירה את
הכותרת Content-Type
:
requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'})
Ruby
כדי לבטל אסימון באופן פרוגרמטי, שולחים בקשת HTTP לנקודת הקצה oauth2.revoke
:
uri = URI('https://oauth2.googleapis.com/revoke') response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
האסימון יכול להיות אסימון גישה או אסימון רענון. אם האסימון הוא אסימון גישה ויש לו אסימון רענון תואם, גם אסימון הרענון יבוטל.
אם הביטול יעובד, קוד הסטטוס של התשובה יהיה 200
. במקרים של שגיאות, מוחזר קוד הסטטוס 400
יחד עם קוד שגיאה.
Node.js
כדי לבטל אסימון באופן פרוגרמטי, שולחים בקשת HTTPS POST לנקודת הקצה של /revoke
:
const https = require('https'); // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end();
פרמטר האסימון יכול להיות אסימון גישה או אסימון רענון. אם האסימון הוא אסימון גישה ויש לו אסימון רענון תואם, גם אסימון הרענון יבוטל.
אם הביטול יעובד, קוד הסטטוס של התשובה יהיה 200
. במקרים של שגיאות, מוחזר קוד הסטטוס 400
יחד עם קוד שגיאה.
HTTP/REST
כדי לבטל אסימון באופן פרוגרמטי, האפליקציה שולחת בקשה ל-https://oauth2.googleapis.com/revoke
וכוללת את האסימון כפרמטר:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
האסימון יכול להיות אסימון גישה או אסימון רענון. אם האסימון הוא אסימון גישה ויש לו אסימון רענון תואם, גם אסימון הרענון יבוטל.
אם הביטול יעובד, קוד סטטוס ה-HTTP של התשובה הוא 200
. במקרים של שגיאות, מוחזר קוד הסטטוס 400
של HTTP יחד עם קוד השגיאה.