חיבור OpenID

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

ניתן להשתמש בממשקי ה-API של OAuth 2.0 לאימות ולהרשאה. במסמך זה מתוארת ההטמעה של OAuth 2.0 לצורך אימות, שתואם למפרט של OpenID Connect. האישור תקף ל-OpenID Certified. המסמכים המפורטים במאמר שימוש ב-OAuth 2.0 כדי לגשת לממשקי API של Google חלים גם על השירות הזה. כדי לחקור את הפרוטוקול באופן אינטראקטיבי, מומלץ להשתמש ב-Google OAuth 2.0 Stadia. לקבלת עזרה בנושא Stack Overflow, אפשר לתייג את השאלות באמצעות התג 'google-oauth'.

הגדרת OAuth 2.0

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

קבלת פרטי כניסה של OAuth 2.0

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

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

לחלופין, צפה בזיהוי הלקוח ובסוד הלקוח שלך מדף האישורים ב API Console :

  1. Go to the Credentials page.
  2. לחץ על שם האישור שלך או על סמל העיפרון ( ). קוד זיהוי הלקוח וסודך נמצאים בראש העמוד.

הגדרת URI של הפניה מחדש

ה-URI של ההפניה שהגדרת ב- API Console קובע את המקומות שבהם Google שולחת תגובות לבקשות האימות שלך.

כדי ליצור, להציג או לערוך את כתובות ה- URI להפניה מחדש עבור אישור נתון OAuth 2.0, בצע את הפעולות הבאות:

  1. Go to the Credentials page.
  2. בקטע מזהי לקוח OAuth 2.0 בדף, לחץ על אישור.
  3. הצגה או עריכה של קבצי ה- URI המפנים מחדש.

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

התאמה אישית של מסך ההסכמה של המשתמש

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

במסך ההסכמה למשתמש מוצגים גם פרטי המיתוג כמו שם המוצר, הלוגו וכתובת האתר של דף הבית. יש לך שליטה בפרטי המיתוג ב API Console.

כדי לאפשר את מסך ההסכמה של הפרויקט שלך:

  1. פתח את Consent Screen page ב- Google API Console .
  2. If prompted, select a project, or create a new one.
  3. מלא את הטופס ולחץ על שמור .

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

צילום מסך של דף הסכמה

גישה לשירות

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

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

מתבצע אימות של המשתמש

אימות המשתמש כולל קבלת אסימון ואימות שלו. אסימוני זיהוי הם תכונה סטנדרטית של OpenID Connect המיועדת לשימוש בהצהרות זהות באינטרנט.

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

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

זרימת שרת

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

  1. יצירת אסימון למצב מניעת זיוף
  2. שליחה של בקשת אימות ל-Google
  3. אשר את אסימון המצב נגד זיוף
  4. Exchange code לאסימון הגישה ולאסימון המזהה
  5. קבלת פרטי משתמש מאסימון המזהה
  6. אימות של המשתמש

1. יצירת אסימון למצב של מניעת זיוף

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

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

הקוד הבא מדגים יצירת אסימוני סשנים ייחודיים.

PHP

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

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = bin2hex(random_bytes(128/8));
$app['session']->set('state', $state);
// Set the client ID, token state, and application name in the HTML while
// serving it.
return $app['twig']->render('index.html', array(
    'CLIENT_ID' => CLIENT_ID,
    'STATE' => $state,
    'APPLICATION_NAME' => APPLICATION_NAME
));

Java

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

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
request.session().attribute("state", state);
// Read index.html into memory, and set the client ID,
// token state, and application name in the HTML before serving it.
return new Scanner(new File("index.html"), "UTF-8")
    .useDelimiter("\\A").next()
    .replaceAll("[{]{2}\\s*CLIENT_ID\\s*[}]{2}", CLIENT_ID)
    .replaceAll("[{]{2}\\s*STATE\\s*[}]{2}", state)
    .replaceAll("[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}",
    APPLICATION_NAME);

Python

עליך להוריד את ספריית הלקוחות של Google APIs עבור Python כדי להשתמש בדוגמה זו.

# Create a state token to prevent request forgery.
# Store it in the session for later validation.
state = hashlib.sha256(os.urandom(1024)).hexdigest()
session['state'] = state
# Set the client ID, token state, and application name in the HTML while
# serving it.
response = make_response(
    render_template('index.html',
                    CLIENT_ID=CLIENT_ID,
                    STATE=state,
                    APPLICATION_NAME=APPLICATION_NAME))

2. שליחת בקשת אימות ל-Google

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

כדי לשלוח בקשה בסיסית, מציינים את הפרמטרים הבאים:

  • client_id, שמקורם ב API Console Credentials page .
  • response_type, שבבקשת זרימה של קוד הרשאה בסיסי צריך להיות code. (מידע נוסף זמין בכתובת response_type.)
  • scope, שבבקשה הבסיסית צריכים להיות openid email. (מידע נוסף זמין בכתובת scope.)
  • הערך redirect_uri צריך להיות נקודת הקצה (endpoint) של HTTP בשרת, שתקבל את התגובה מ-Google. הערך צריך להיות זהה לאחד ממזהי ה-URI המורשים של לקוח OAuth 2.0, שמוגדר ב- API ConsoleCredentials page. אם הערך לא תואם ל-URI מאושר, הבקשה תיכשל ותוצג שגיאה מסוג redirect_uri_mismatch.
  • state צריך לכלול את הערך של אסימון הסשן הייחודי נגד זיוף, וכל פרט אחר שדרוש כדי לשחזר את ההקשר כשהמשתמש חוזר לאפליקציה, למשל כתובת ה-URL להתחלה. (מידע נוסף זמין בכתובת state.)
  • nonce הוא ערך אקראי שנוצר על ידי האפליקציה שלך ומאפשר הגנת הפעלה מחדש כשהוא נמצא.
  • הערך login_hint יכול להיות כתובת האימייל של המשתמש או מחרוזת ה-sub, המקבילה למזהה Google של המשתמש. אם לא מוסרים את login_hint והמשתמש מחובר כרגע, מסך ההסכמה כולל בקשה לאישור שחרור כתובת האימייל של המשתמש לאפליקציה. (מידע נוסף זמין בכתובת login_hint).
  • ניתן להשתמש בפרמטר hd כדי לבצע אופטימיזציה של התהליך של OpenID Connect למשתמשים בדומיין מסוים המשויכים לארגון ב-Google Cloud. (מידע נוסף זמין בכתובת hd.)

הנה דוגמה ל-URI מלא של אימות OpenID Connect, עם מעברי שורה ורווחים לקריאות:

https://accounts.google.com/o/oauth2/v2/auth?
 response_type=code&
 client_id=424911365001.apps.googleusercontent.com&
 scope=openid%20email&
 redirect_uri=https%3A//oauth2.example.com/code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2-login-demo.example.com%2FmyHome&
 login_hint=jsmith@example.com&
 nonce=0394852-3190485-2490358&
 hd=example.com

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

3. אישור אסימון במצב נגד זיוף

התגובה נשלחת אל redirect_uri שציינת בבקשה. כל התגובות מוחזרות במחרוזת השאילתה, כפי שמוצג בהמשך:

https://oauth2.example.com/code?state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foa2cb.example.com%2FmyHome&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&scope=openid%20email%20https://www.googleapis.com/auth/userinfo.email

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

הקוד הבא מוכיח את אסימוני הסשן שיצרתם בשלב 1:

PHP

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

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
  return new Response('Invalid state parameter', 401);
}

Java

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

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if (!request.queryParams("state").equals(
    request.session().attribute("state"))) {
  response.status(401);
  return GSON.toJson("Invalid state parameter.");
}

Python

עליך להוריד את ספריית הלקוחות של Google APIs עבור Python כדי להשתמש בדוגמה זו.

# Ensure that the request is not a forgery and that the user sending
# this connect request is the expected user.
if request.args.get('state', '') != session['state']:
  response = make_response(json.dumps('Invalid state parameter.'), 401)
  response.headers['Content-Type'] = 'application/json'
  return response

4. העברה של code לאסימון הגישה ולאסימון המזהה

התגובה כוללת פרמטר code, קוד הרשאה חד-פעמי, שהשרת יכול להחליף ביניהם באסימון גישה ובאסימון מזהה. השרת שלך מבצע את ההחלפה הזו על ידי שליחת בקשת HTTPS מסוג POST. הבקשה POST נשלחת לנקודת הקצה של האסימון, שיש לאחזר ממסמך ה-Discovery באמצעות ערך המטא-נתונים של token_endpoint. בדיון הבא ההנחה היא שנקודת הקצה היא https://oauth2.googleapis.com/token. הבקשה חייבת לכלול את הפרמטרים הבאים בגוף (POST):

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

הבקשה בפועל עשויה להיראות כמו בדוגמה הבאה:

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

תגובה מוצלחת לבקשה הזו מכילה את השדות הבאים במערך JSON:

שדות
access_token אסימון שניתן לשלוח ל-Google API.
expires_in משך החיים הנותר של אסימון הגישה בשניות.
id_token JWT המכיל פרטי זהות של המשתמש שחתום על ידי Google באופן דיגיטלי.
scope היקפי הגישה שניתנו על ידי ה-access_token מוצגים כרשימה של מחרוזות שתלויות ברווחים ותלויות ברווחים.
token_type מזהה של סוג האסימון שהוחזר. בשלב זה, השדה הזה תמיד מכיל את הערך Bearer.
refresh_token (אופציונלי)

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

5. קבלת פרטי משתמש מאסימון המזהה

אסימון מזהה הוא JWT (JSON Web Token), כלומר, אובייקט JSON בקידוד 66 עם קידוד קריפטוגרפי. בדרך כלל חשוב מאוד לאמת אסימון מזהה לפני שמשתמשים בו, אבל מכיוון שיש לך תקשורת ישירה עם Google בערוץ HTTPS ללא מתווך, ומשתמש בסוד הלקוח כדי לאמת את עצמך מול Google, את יכולה להיות בטוחה שהאסימון שקיבלת אכן הגיע מ-Google ושהוא תקין. אם השרת מעביר את אסימון המזהה לרכיבים אחרים באפליקציה, חשוב מאוד שהרכיבים האחרים יאמתו את האסימון לפני שמשתמשים בו.

מאחר שרוב ספריות ה-API משלבות את האימות עם פענוח הערכים בקידוד base64url וניתוח ה-JSON שבתוכו, בסופו של דבר בסופו של דבר אימתנו את האסימון בכל פעם שתיגש לתלונות באסימון המזהה.

מטען ייעודי (payload) של אסימון מזהה

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

{
  "iss": "https://accounts.google.com",
  "azp": "1234987819200.apps.googleusercontent.com",
  "aud": "1234987819200.apps.googleusercontent.com",
  "sub": "10769150350006150715113082367",
  "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
  "hd": "example.com",
  "email": "jsmith@example.com",
  "email_verified": "true",
  "iat": 1353601026,
  "exp": 1353604926,
  "nonce": "0394852-3190485-2490358"
}

אסימוני Google ID עשויים להכיל את השדות הבאים (המכונים תביעות):

דירוג מוגדרים תיאור
aud always קהל היעד של האסימון הזה. הוא חייב להיות אחד ממזהי הלקוח ב-OAuth 2.0 של האפליקציה שלך.
exp always מועד התפוגה שאחריו או לא ניתן לקבל את אסימון המזהה. מיוצגת בזמן Unix (מספר שלם).
iat always מועד הנפקת האסימון. מיוצג בזמן Unix (מספר שלם).
iss always מזהה המנפיק של מנפיק התשובה. תמיד https://accounts.google.com או accounts.google.com לאסימוני המזהה של Google.
sub always מזהה עבור המשתמש, הייחודי בין כל חשבונות Google ולעולם לא נעשה בו שימוש חוזר. לחשבון Google יכולות להיות כמה כתובות אימייל בנקודות זמן שונות, אבל הערך של sub לעולם לא משתנה. יש להשתמש בקוד sub באפליקציה כמפתח המזהה הייחודי של המשתמש. האורך המקסימלי הוא 255 תווי ASCII תלויי אותיות רישיות.
at_hash גיבוב (hash) של אסימון גישה. המדיניות מספקת אימות שאסימון הגישה מקושר לאסימון הזהות. אם אסימון הזיהוי מונפק עם ערך access_token בתהליך השרת, התלונה הזו תמיד נכללת. אפשר להשתמש בתלונה הזו כמנגנון חלופי להגנה מפני מתקפות זיוף של בקשות בין אתרים, אבל אם פועלים לפי שלב 1 ושלב 3, אין צורך לאמת את אסימון הגישה.
azp client_id של המציג המורשה. תביעת הבעלות הזו נדרשת רק כשהגורם שמבקש את אסימון המזהה שונה מהקהל של אסימון המזהה. זה יכול להיות המצב ב-Google לאפליקציות היברידיות, שבהן לאפליקציית אינטרנט ולאפליקציית Android יש פרוטוקול OAuth 2.0 שונה. client_id, אותו פרויקט Google APIs.
email זוהי כתובת האימייל של המשתמש. יכול להיות שהערך הזה לא ייחודי למשתמש הזה, והוא לא מתאים לשימוש כמפתח ראשי. סופק רק אם ההיקף שלך כלל את ערך ההיקף של email.
email_verified הערך הוא True אם כתובת האימייל של המשתמש אומתה. אחרת, הערך הוא False.
family_name שמות המשפחה או שמות המשפחה של המשתמש. אפשר לציין זאת אם יש תלונה name.
given_name השם הפרטי או השם הפרטי של המשתמש. אפשר לציין זאת אם יש תלונה name.
hd הדומיין שמשויך לארגון של המשתמש ב-Google Cloud. מסופק רק אם המשתמש שייך לארגון ב-Google Cloud.
locale הלוקאל של המשתמש, מיוצג על ידי תג שפה מסוג BCP 47. אפשר לציין זאת אם יש תלונה של name.
name השם המלא של המשתמש, בצורה ניתנת להצגה. אפשר לציין את הפרטים הבאים:
  • היקף הבקשות כלל את המחרוזת "פרופיל"
  • אסימון המזהה מוחזר מרענון אסימון

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

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

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

profile כתובת ה-URL של דף הפרופיל של המשתמש. אפשר לציין את הפרטים הבאים:
  • היקף הבקשות כלל את המחרוזת "פרופיל"
  • אסימון המזהה מוחזר מרענון אסימון

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

6. יש לאמת את המשתמש

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

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

נושאים מתקדמים

הקטעים הבאים מתארים בפירוט רב יותר את Google OAuth 2.0 API. המידע הזה מיועד למפתחים עם דרישות מתקדמות לגבי אימות והרשאה.

גישה לממשקי Google API אחרים

אחד מהיתרונות של השימוש ב-OAuth 2.0 לאימות הוא שהאפליקציה יכולה לקבל הרשאה לשימוש בממשקי Google API אחרים מטעם המשתמש (כמו YouTube , Google Drive, היומן או אנשי הקשר) במקביל לאימות המשתמש. כדי לעשות זאת, יש לכלול את ההיקפים האחרים שדרושים בבקשת האימות ששולחים ל-Google. לדוגמה, כדי להוסיף את קבוצת הגיל של המשתמש לבקשת האימות, צריך להעביר פרמטר היקף של openid email https://www.googleapis.com/auth/profile.agerange.read. תוצג בקשה למשתמש במסך ההסכמה. אסימון הגישה שקיבלת בחזרה מ-Google מאפשר לך לגשת לכל ממשקי ה-API הקשורים להיקפי הגישה שביקשת, שהוענקו לך.

רענון האסימונים

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

שיקולים:

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

מידע נוסף זמין במאמר רענון של אסימון גישה (גישה אופליין).

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

מידע נוסף על הפרמטר prompt זמין בטבלה prompt בטבלה פרמטרים של URI לאימות.

פרמטרים של URI לאימות

בטבלה הבאה מפורטים תיאורים מלאים יותר של הפרמטרים ש-Google מאמתת את OAuth 2.0.

פרמטר נדרש תיאור
client_id (נדרש) המחרוזת של מזהה הלקוח שקיבלתם ב- API ConsoleCredentials page, כמתואר במאמר קבלת פרטי כניסה של OAuth 2.0.
nonce (נדרש) ערך אקראי שנוצר על ידי האפליקציה שלך ומאפשר הפעלה מחדש של ההגנה.
response_type (נדרש) אם הערך הוא code, יושק תהליך קוד אימות בסיסי שידרוש POST לנקודת הקצה של האסימון כדי לקבל את האסימונים. אם הערך הוא token id_token או id_token token, מופעל תהליך משתמע, שמחייב שימוש ב-JavaScript ב-URI של ההפניה האוטומטית כדי לאחזר אסימונים מהמזהה URI של #fragment.
redirect_uri (נדרש) קובע לאן התגובה תישלח. הערך של הפרמטר הזה צריך להיות זהה לאחד מערכי ההפניה האוטומטית המורשים שמוגדרים ב- API ConsoleCredentials page (כולל סכימת ה-HTTP או ה-HTTPS, אות ← ואחריה אם יש).
scope (נדרש)

פרמטר ההיקף צריך להתחיל בערך openid ולאחר מכן לכלול את הערך profile, את הערך email או את שניהם.

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

אם קיים ערך היקף של email, אסימון המזהה כולל email ו-email_verified תלונות.

בנוסף להיקפים הספציפיים ל-OpenID, ארגומנט ההיקף יכול לכלול גם ערכי היקף אחרים. כל ערכי ההיקף צריכים להיות מופרדים ברווחים. לדוגמה, אם רציתם לגשת לכל קובץ ב-Google Drive של משתמש מסוים, פרמטר ההיקף יכול להיות openid profile email https://www.googleapis.com/auth/drive.file.

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

state (אופציונלי, אבל מומלץ מאוד)

מחרוזת אטומה שחוצה את הפרוטוקול. כלומר, היא מוחזרת כפרמטר של URI בזרימה הבסיסית ובמזהה ה-URI #fragment בזרימה המשתמעת.

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

access_type (לא חובה) הערכים המותרים הם offline ו-online. ההשפעה מתועדת בגישה אופליין. אם התבקש אסימון גישה, הלקוח לא יקבל אסימון רענון אלא אם צוין ערך offline.
display (לא חובה) ערך מחרוזת ASCII כדי לציין איך שרת ההרשאות יציג את דפי הממשק של המשתמש לאימות ולהסכמה. הערכים הבאים מצוינים על ידי שרתי Google, אך לא משפיעים על אופן הפעולה שלהם: page, popup, touch ו-wap.
hd (לא חובה)

ייעול תהליך ההתחברות בחשבונות שבבעלות ארגון ב-Google Cloud. אפשר לכלול את הדומיין של הארגון ב-Google Cloud (לדוגמה, mycollege.edu), כדי לציין שחוויית המשתמש לבחירת החשבון תבוצע רק בחשבונות שבדומיין הזה. כדי לבצע אופטימיזציה עבור חשבונות ארגוניים של Google Cloud, ולא רק עבור דומיין ארגוני אחד של Google Cloud, יש להגדיר כוכבית (*): hd=*.

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

include_granted_scopes (לא חובה) אם הפרמטר הזה מסופק עם הערך true, ובקשת ההרשאה ניתנת, ההרשאה תכלול את כל ההרשאות הקודמות שהוענקו לשילוב של משתמש/אפליקציה זה עבור היקפים אחרים. מידע נוסף מופיע בהרשאה מצטברת.

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

login_hint (לא חובה) כשהאפליקציה מזהה את המשתמש שהיא מנסה לאמת, היא יכולה לספק את הפרמטר הזה כרמז לשרת האימות. העברת הרמז הזה מסתירה את בוחר החשבונות וממלאה מראש את תיבת האימייל בטופס הכניסה. לחלופין, היא בוחרת בסשן המתאים (אם המשתמש משתמש בכניסה עם מספר חשבונות), וכך אפשר למנוע בעיות שמתרחשות אם האפליקציה רשומה בחשבון המשתמש הלא נכון. הערך יכול להיות כתובת אימייל או מחרוזת sub, שדומה למזהה Google של המשתמש.
prompt (לא חובה) רשימה מופרדת ברווחים של ערכי מחרוזת שמציינת אם שרת ההרשאות מבקש מהמשתמש אימות מחדש והסכמה. הערכים האפשריים הם:
  • none

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

  • consent

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

  • select_account

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

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

אימות של אסימון זיהוי

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

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

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

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

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

לאימות של אסימון זיהוי נדרשים כמה שלבים:

  1. יש לוודא שאסימון המזהה חתום כראוי על ידי המנפיק. אסימונים שהונפקו על ידי Google חתומים באמצעות אחד מהאישורים שנמצאים ב-URI שצוין בערך המטא-נתונים של jwks_uri של מסמך הגילוי.
  2. יש לוודא שערך הבעלות על iss באסימון המזהה שווה ל-https://accounts.google.com או ל-accounts.google.com.
  3. עליך לוודא שהערך של התלונה aud באסימון המזהה זהה למספר הלקוח של האפליקציה.
  4. יש לוודא שמועד התפוגה (תביעת בעלות של exp) של אסימון המזהה לא עבר.
  5. אם ציינת ערך פרמטר hd בבקשה, עליך לאמת של אסימון המזהה יש תביעת hd התואמת לדומיין קביל המשויך לארגון ב-Google Cloud.

שלבים 2 עד 5 כוללים רק השוואות של מחרוזות תאריכים שהן פשוטות למדי, ולכן לא נפרט אותן כאן.

השלב הראשון הוא מורכב יותר וכולל בדיקה של חתימה קריפטוגרפית. למטרות ניפוי באגים, אפשר להשתמש בנקודת הקצה tokeninfo של Google כדי להשוות בין עיבוד מקומי שמוטמע בשרת או במכשיר. נניח שהערך של אסימון הזיהוי שלך הוא XYZ123. לאחר מכן יש להפנות ל-URI https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123. אם חתימת האסימון חוקית, התגובה תהיה מטען ייעודי (payload) של JWT בצורת אובייקט JSON מפוענח.

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

Google משנה את המפתחות הציבוריים שלה לעתים רחוקות בלבד, ולכן אפשר לשמור אותם במטמון באמצעות ההנחיות למטמון של תגובת ה-HTTP, וברוב המקרים לבצע אימות מקומי ביעילות רבה יותר מאשר באמצעות נקודת הקצה tokeninfo. האימות הזה מצריך אחזור וניתוח של אישורים, וביצוע הקריאות הקריפטוגרפיות המתאימות כדי לבדוק את החתימה. למרבה המזל, יש ספריות רבות לניפוי באגים הזמינות במגוון רחב של שפות (ראו jwt.io).

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

כדי לקבל פרטי פרופיל נוספים על המשתמש, ניתן להשתמש באסימון הגישה שהאפליקציה מקבלת (בזמן תהליך האימות) ובתקן OpenID Connect:

  1. כדי לעמוד בדרישות OpenID, עליך לכלול את ערכי ההיקף של openid profile בבקשת האימות.

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

    scope=openid%20profile%20email
  2. יש להוסיף את אסימון הגישה לכותרת ההרשאה ולשלוח בקשת HTTPS מסוג GET לנקודת הקצה של פרטי המשתמש, שיש לאחזר ממסמך ה-Discovery באמצעות ערך המטא-נתונים של userinfo_endpoint. תגובת ה-userinfo כוללת מידע על המשתמש, כפי שמתואר ב-OpenID Connect Standard Claims ובערך המטא-נתונים של claims_supported במסמך Discovery. יכול להיות שמשתמשים או הארגונים שלהם בחרו לספק או להסתיר שדות מסוימים, לכן יכול להיות שלא תהיה לך אפשרות לקבל מידע על כל שדה להיקפי הגישה המורשים שלך.

מסמך הגילוי

פרוטוקול OpenID Connect מחייב שימוש בנקודות קצה מרובות לאימות משתמשים, וכדי לבקש משאבים, כולל אסימונים, פרטי משתמשים ומפתחות ציבוריים.

כדי לפשט את ההטמעה ולהגדיל את הגמישות, OpenID Connect מאפשר להשתמש ב'מסמך Discovery' – מסמך JSON שנמצא במיקום מפורסם שמכיל צמדי מפתח/ערך, ומספק פרטים על התצורה של ספק ה-OpenID Connect, כולל כתובות ה-URI של ההרשאות, האסימון, הביטול, פרטי המשתמש ונקודות הקצה של מפתחות ציבוריים. ניתן לאחזר את מסמך ה-Discovery עבור שירות OpenID Connect של Google מ:

https://accounts.google.com/.well-known/openid-configuration

כדי להשתמש בשירותי OpenID Connect של Google, עליך ליצור בתוך הקוד את ה-URI של מסמך Discovery https://accounts.google.com/.well-known/openid-configuration. האפליקציה מאחזרת את המסמך, מחילה את כללי השמירה במטמון בתגובה, ולאחר מכן מאחזרת מזהי URI של נקודת הקצה לפי הצורך. לדוגמה, כדי לאמת משתמש, הקוד יאחזר את הערך של המטא-נתונים authorization_endpoint (https://accounts.google.com/o/oauth2/v2/auth בדוגמה שלמטה) בתור ה-URI הבסיסי של בקשות האימות שנשלחות אל Google.

זוהי דוגמה למסמך כזה. שמות השדות הם אלה שצוינו ב-OpenID Connect Discovery 1.0 (יש לעיין במסמך הזה בהתאם למשמעות שלהם). הערכים נועדו להמחשה בלבד והם עשויים להשתנות, אף על פי שהם הועתקו מגרסה עדכנית של מסמך Google Discovery עצמו:

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "code token",
    "code id_token",
    "token id_token",
    "code token id_token",
    "none"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "scopes_supported": [
    "openid",
    "email",
    "profile"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic"
  ],
  "claims_supported": [
    "aud",
    "email",
    "email_verified",
    "exp",
    "family_name",
    "given_name",
    "iat",
    "iss",
    "locale",
    "name",
    "picture",
    "sub"
  ],
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ]
}

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

ספריות לקוח

ספריות הלקוח הבאות הופכות את השימוש ב-OAuth 2.0 לפשוט יותר על ידי שילוב עם מסגרות פופולריות:

תאימות ל-OpenID Connect

מערכת האימות של OAuth 2.0 של Google תומכת בתכונות הדרושות במפרט של OpenID Connect Core. כל לקוח שמיועד לעבוד עם OpenID Connect צריך לעבוד בשיתוף פעולה עם שירות זה (למעט אובייקט בקשת OpenID).