OAuth 2.0 לאפליקציות אינטרנט בצד הלקוח

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

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

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

ספריית הלקוח של Google APIs ושירותי Google Identity

אם משתמשים בספריית הלקוח של Google APIs עבור JavaScript כדי לבצע קריאות מורשות ל-Google, צריך להשתמש בספריית JavaScript של Google Identity Services כדי לטפל בתהליך OAuth 2.0. מומלץ לעיין במודל האסימון של Google Identity Services, שמבוסס על תהליך ההענקת גישה משתמעת ב-OAuth 2.0.

דרישות מוקדמות

הפעלת ממשקי API בפרויקט

כל אפליקציה שקוראת ל-Google APIs צריכה להפעיל את ממשקי ה-API האלה ב- API Console.

כדי להפעיל ממשק API בפרויקט:

  1. Open the API Library ב Google API Console.
  2. If prompted, select a project, or create a new one.
  3. בטבלה API Library מפורטים כל ממשקי ה-API הזמינים, מקובצים לפי משפחת המוצרים והפופולריות שלהם. אם ה-API שרוצים להפעיל לא מופיע ברשימה, תוכלו להיעזר בחיפוש כדי למצוא אותו או ללחוץ על הצגת הכול במשפחת המוצרים שאליה הוא שייך.
  4. בוחרים את ה-API שרוצים להפעיל ולוחצים על הלחצן הפעלה.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

יצירת פרטי כניסה להרשאה

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

  1. Go to the Credentials page.
  2. לוחצים על Create credentials > OAuth client ID.
  3. בוחרים בסוג האפליקציה אפליקציית אינטרנט.
  4. ממלאים את הטופס. באפליקציות שמשתמשות ב-JavaScript כדי לשלוח בקשות מורשות ל-Google API, חייבים לציין מקורות JavaScript מורשים. מקורות הנתונים מזהים את הדומיינים שמהם האפליקציה שלך יכולה לשלוח בקשות לשרת OAuth 2.0. המקורות האלה חייבים לעמוד בכללי האימות של Google.

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

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

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

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

קבלת אסימוני גישה מסוג OAuth 2.0

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

שלב 1: הפניה אוטומטית לשרת OAuth 2.0 של Google

כדי לבקש הרשאת גישה לנתוני משתמש, יש להפנות את המשתמש לשרת OAuth 2.0 של Google.

נקודות קצה ב-OAuth 2.0

צריך ליצור כתובת URL כדי לבקש גישה מנקודת הקצה 2.0 של OAuth ב-https://accounts.google.com/o/oauth2/v2/auth. ניתן לגשת לנקודת הקצה הזו דרך HTTPS. סירובם של חיבורי HTTP פשוטים.

שרת ההרשאות של Google תומך בפרמטרים הבאים של מחרוזת שאילתה באפליקציות של שרת אינטרנט:

פרמטרים
client_id נדרש

מזהה הלקוח של האפליקציה שלך. אפשר למצוא את הערך הזה ב- API Console Credentials page.

redirect_uri נדרש

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

חשוב לשים לב ש-http או https הסכימה, הפנייה והקו הנטוי העוקב ('/') חייבים להתאים לכולם.

response_type נדרש

באפליקציות JavaScript, צריך להגדיר את ערך הפרמטר ל-token. הערך הזה מורה לשרת ההרשאות של Google להחזיר את אסימון הגישה כצמד name=value במזהה המקטע של ה-URI (#) שאליו המשתמש מופנה מחדש אחרי השלמת תהליך ההרשאה.

scope נדרש

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

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

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

state מומלץ

מציינת את ערך המחרוזת שמשמש את האפליקציה כדי לשמור על מצב בין בקשת ההרשאה שלך לבין התגובה של שרת ההרשאות. השרת מחזיר את הערך המדויק ששלחת כצמד name=value במזהה הקטע של כתובת ה-URL (#) של ה-redirect_uri, אחרי שהמשתמש מסכים או דוחה את בקשת הגישה של האפליקציה שלך.

אפשר להשתמש בפרמטר הזה למטרות שונות. למשל, הפניית המשתמש למשאב הנכון באפליקציה, שליחת אירועים ללא מענה וצמצום זיוף של בקשות בין אתרים. מכיוון שאפשר לנחש את redirect_uri, שימוש בערך state יכול להגביר את ההבטחה שחיבור נכנס נובע מבקשת אימות. אם יוצרים מחרוזת אקראית או מקודדים גיבוב (hash) של קובץ cookie או ערך אחר שמתעד את מצב הלקוח, אפשר לאמת את התשובה כדי לוודא שהבקשה ותגובה נוצרו באותו דפדפן, וכך לספק הגנה מפני מתקפות כמו זיוף בקשות באתרים שונים. במסמכי התיעוד של OpenID Connect אפשר לראות דוגמה ליצירה ולאישור של אסימון state.

include_granted_scopes אופציונלי

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

login_hint אופציונלי

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

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

prompt אופציונלי

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

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

none אין להציג מסכי אימות או הסכמה. אי אפשר לציין אותו עם ערכים אחרים.
consent בקשת הסכמה מהמשתמשים.
select_account בקשה למשתמש לבחור חשבון.

דוגמה של הפניה אוטומטית לשרת ההרשאות של Google

לפניכם כתובת URL לדוגמה עם מעברי שורה ורווחים לקריאות.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

אחרי שיוצרים את כתובת ה-URL של הבקשה, מפנים את המשתמש אליה.

קוד לדוגמה של JavaScript

קטע ה-JavaScript הבא מראה איך להפעיל את תהליך ההרשאה ב-JavaScript בלי להשתמש בספריית הלקוח של Google APIs עבור JavaScript. נקודת הקצה הזו של OAuth 2.0 לא תומכת בשיתוף משאבים בין מקורות (CORS), ולכן קטע הקוד יוצר טופס שפותח את הבקשה מנקודת הקצה הזו.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

שלב 2: Google מבקשת מהמשתמשים הסכמה

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

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

שגיאות

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

admin_policy_enforced

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

disallowed_useragent

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

Android

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

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

iOS

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

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

org_internal

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

invalid_client

המקור שממנו הבקשה נשלחה אינו מורשה ללקוח הזה. מידע נוסף זמין ב-origin_mismatch.

invalid_grant

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

origin_mismatch

הסכימה, הדומיין ו/או היציאה של ה-JavaScript שמהם נשלחה בקשת ההרשאה לא תואמים ל-URI מורשה של מקור ה-JavaScript הרשום עבור מספר הלקוח של OAuth. בדיקה של מקורות JavaScript מורשים ב- Google API Console Credentials page.

redirect_uri_mismatch

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

הסכימה, הדומיין ו/או היציאה של ה-JavaScript שמהם נשלחה בקשת ההרשאה לא תואמים ל-URI מורשה של מקור ה-JavaScript הרשום עבור מספר הלקוח של OAuth. בדיקה של מקורות JavaScript מורשים ב- Google API Console Credentials page.

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

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

נקודות קצה ב-OAuth 2.0

שרת OAuth 2.0 שולח תגובה אל redirect_uri שצוין בבקשת אסימון הגישה שלך.

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

  • תשובה של אסימון גישה:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

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

  • הודעת שגיאה:
    https://oauth2.example.com/callback#error=access_denied

דוגמה לתגובה של שרת OAuth 2.0

תוכלו לבדוק את התהליך הזה בלחיצה על כתובת ה-URL לדוגמה הבאה, שמבקשת גישה לקריאה בלבד כדי להציג מטא-נתונים של קבצים ב-Google Drive:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

אחרי השלמת תהליך OAuth 2.0, המערכת תפנה אותך אל http://localhost/oauth2callback. כתובת ה-URL הזו תייצר שגיאה מסוג 404 NOT FOUND, אלא אם המכונה המקומית שלך תציג קובץ בכתובת הזו. השלב הבא מספק פרטים נוספים על המידע שמוחזר ב-URI כשהמשתמש מופנה בחזרה לאפליקציה.

קריאה ל-Google APIs

נקודות קצה ב-OAuth 2.0

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

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

דוגמאות ל-HTTP GET

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

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

זוהי קריאה לאותו API עבור המשתמש המאומת באמצעות הפרמטר access_token של מחרוזת השאילתה:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

curl דוגמאות

אפשר לבדוק את הפקודות האלה באמצעות האפליקציה curl של שורת הפקודה. הנה דוגמה שמשתמשת באפשרות של כותרת HTTP (מועדף):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

לחלופין, אפשרות הפרמטר של מחרוזת השאילתה:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

קוד לדוגמה של JavaScript

קטע הקוד שבהמשך מדגים איך להשתמש ב-CORS (שיתוף משאבים בין מקורות) כדי לשלוח בקשה ל-Google API. בדוגמה זו לא נעשה שימוש בספריית הלקוח של Google APIs עבור JavaScript. עם זאת, גם אם אתם לא משתמשים בספריית הלקוח, תוכלו להיעזר במדריך התמיכה של CORS במסמכי התיעוד של הספרייה, כדי להבין טוב יותר את הבקשות האלה.

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

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

דוגמה מלאה

נקודות קצה ב-OAuth 2.0

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

בתהליך OAuth 2.0, הדף פועל לפי השלבים הבאים:

  1. המערכת מפנה את המשתמש לשרת OAuth 2.0 של Google שמבקש גישה להיקף של https://www.googleapis.com/auth/drive.metadata.readonly.
  2. אחרי שנותנים (או דוחים) גישה להיקף אחד או יותר מהבקשות, המשתמש מופנה לדף המקורי, שמנתח את אסימון הגישה ממחרוזת המזהה של קטע הקוד.
  3. הדף משתמש באסימון הגישה כדי לשלוח את בקשת ה-API לדוגמה.

    בקשת ה-API שולחת קריאה ל-method about.get של ה-API של Drive כדי לאחזר מידע על חשבון Google Drive של המשתמש המורשה.

  4. אם הבקשה תבוצע בהצלחה, תגובת ה-API תתועד במסוף ניפוי הבאגים של הדפדפן.

אפשר לבטל את הגישה לאפליקציה דרך הדף הרשאות בחשבון Google. שם האפליקציה יהיה הדגמה של OAuth 2.0 ל-Google API Docs.

כדי להפעיל את הקוד באופן מקומי, עליך להגדיר ערכים למשתנים YOUR_CLIENT_ID ו-YOUR_REDIRECT_URI שתואמים לפרטי הכניסה להרשאה שלך. צריך להגדיר את המשתנה YOUR_REDIRECT_URI עם אותה כתובת URL שבה הדף מוצג. הערך חייב להתאים במדויק לאחד ממזהי ה-URI המופנים מחדש של לקוח OAuth 2.0, שהגדרת ב- API Console Credentials page. אם הערך הזה לא תואם ל-URI מורשה, תתקבל שגיאה redirect_uri_mismatch. בנוסף, הפרויקט שלכם צריך להפעיל את ה-API המתאים בבקשה הזו.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

כללי אימות מקור של JavaScript

Google מחילה את כללי האימות הבאים על מקורות JavaScript כדי לעזור למפתחים לשמור על אבטחת האפליקציות שלהם. מקורות ה-JavaScript חייבים לעמוד בכללים האלה. בסעיף RFC 3986 סעיף 3 מפורט ההגדרה של דומיין, מארח וסכימה, כפי שמפורט בהמשך.

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

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

מארח

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

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

    מקורות JavaScript לא יכולים להכיל את רכיב המשנה userinfo.

    נתיב

    מקורות JavaScript לא יכולים להכיל את רכיב הנתיב.

    שאילתה

    מקורות JavaScript לא יכולים להכיל את רכיב השאילתה.

    קטע

    מקורות JavaScript לא יכולים להכיל את רכיב המקטע.

    תווים מקורות JavaScript לא יכולים להכיל תווים מסוימים, כולל:
    • תווים כלליים לחיפוש ('*')
    • תווי ASCII שאינם ניתנים להדפסה
    • קידודים באחוזים לא חוקיים (קידוד כלשהו באחוזים שאינו תואם לצורת הקידוד של כתובת URL של סימן אחוז ואחריו שתי ספרות הקסדצימליות)
    • תווי null (תו NULL מקודד, למשל, %00, %C0%80)

    הרשאה מצטברת

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

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

    במקרה כזה, בזמן הכניסה לאפליקציה, האפליקציה עשויה לבקש מההיקפים openid ו-profile לבצע כניסה בסיסית, ולאחר מכן תבקש את ההיקף של https://www.googleapis.com/auth/drive.file בזמן הבקשה הראשונה כדי לשמור מיקס.

    הכללים הבאים חלים על אסימון גישה שמתקבל מהרשאה מצטברת:

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

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

    נקודות קצה ב-OAuth 2.0

    כדי להוסיף היקפים לאסימון גישה קיים, יש לכלול את הפרמטר include_granted_scopes בבקשה לשרת OAuth 2.0 של Google.

    קטע הקוד הבא מראה איך לעשות זאת. קטע הקוד מניח ששמרת את ההיקפים שעבורם אסימון הגישה שלך חוקי באחסון המקומי של הדפדפן. (הקוד לדוגמה המלא מאחסן רשימה של היקפים שעבורם אסימון הגישה חוקי. כדי לעשות זאת, מגדירים את הנכס oauth2-test-params.scope באחסון המקומי של הדפדפן.)

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

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    ביטול אסימון

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

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

    נקודות קצה ב-OAuth 2.0

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

    קטע הקוד הבא של JavaScript מראה איך לבטל אסימון ב-JavaScript, בלי להשתמש בספריית הלקוח של Google APIs עבור JavaScript. מאחר שנקודת הקצה של Google OAuth 2.0 לביטול אסימונים לא תומכת בשיתוף משאבים בין מקורות (CORS), הקוד יוצר טופס ושולח את הטופס אל נקודת הקצה ולא את השיטה XMLHttpRequest() כדי לפרסם את הבקשה.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }