אפשר להשתמש בממשקי ה-API של Google מסוג OAuth 2.0 גם לאימות וגם להרשאה. במסמך הזה מתוארת הטמעת OAuth 2.0 לאימות, שתואמת למפרט של OpenID Connect ומאושרת על ידי OpenID. המסמכים במאמר שימוש ב-OAuth 2.0 כדי לגשת אל Google APIs רלוונטיים גם לשירות הזה. אם אתם רוצים לבדוק את הפרוטוקול הזה באופן אינטראקטיבי, מומלץ להשתמש ב-Google OAuth 2.0 Playground. כדי לקבל עזרה ב-Stack Overflow, תייגו את השאלות שלכם בתג google-oauth.
הגדרת OAuth 2.0
כדי שהאפליקציה תוכל להשתמש במערכת האימות OAuth 2.0 של Google להתחברות של משתמשים, צריך להגדיר פרויקט ב-מסוף Google Cloud כדי לקבל את פרטי הכניסה ל-OAuth 2.0, להגדיר URI להפניה אוטומטית וגם (אופציונלי) להתאים אישית את פרטי המיתוג שהמשתמשים רואים במסך ההסכמה. אפשר גם להשתמש במסוף Cloud כדי ליצור חשבון שירות, להפעיל חיוב, להגדיר סינון ולבצע משימות אחרות. לפרטים נוספים, קראו את העזרה של מסוף Google Cloud.
קבלת פרטי כניסה ל-OAuth 2.0
כדי לאמת משתמשים ולקבל גישה לממשקי ה-API של Google, אתם צריכים פרטי כניסה ל-OAuth 2.0, כולל מזהה לקוח וסוד לקוח.
כדי לראות את מזהה הלקוח וסוד הלקוח של פרטי כניסה מסוימים של OAuth 2.0, לוחצים על הטקסט Select credential. בחלון שנפתח, בוחרים את הפרויקט ואת פרטי הכניסה הרצויים ולוחצים על View.
אפשר גם לראות את מזהה הלקוח וסוד הלקוח בדף Clients במסוף Cloud:
- עוברים אל הדף "לקוחות".
- לוחצים על שם הלקוח או על סמל העריכה (create). מזהה הלקוח והסוד מופיעים בחלק העליון של הדף.
הגדרת URI של הפניה אוטומטית
ה-URI להפניה אוטומטית שהגדרתם במסוף Cloud קובע לאן Google תשלח את התשובות לבקשות האימות שלכם.
כדי ליצור, להציג או לערוך את כתובות ה-URI להפניה אוטומטית של פרטי כניסה מסוימים ל-OAuth 2.0:
- עוברים אל הדף "לקוחות".
- לוחצים על הלקוח.
- צפייה או עריכה של כתובות ה-URI להפניה אוטומטית.
אם לא מופיע לקוח בדף Clients, לפרויקט אין פרטי כניסה ל-OAuth. כדי ליצור לקוח, לוחצים על יצירת לקוח.
התאמה אישית של מסך הסכמת המשתמש
חוויית האימות של OAuth 2.0 כוללת מסך הסכמה שמתאר את המידע שהמשתמש משחרר ואת התנאים שחלים. לדוגמה, כשהמשתמש מתחבר, יכול להיות שהוא יתבקש לתת לאפליקציה גישה לכתובת האימייל שלו ולמידע בסיסי על החשבון. כדי לבקש גישה למידע הזה, משתמשים בפרמטר scope, שהאפליקציה כוללת בבקשת האימות שלה. אפשר גם להשתמש בהיקפי הרשאות כדי לבקש גישה לממשקי Google API אחרים.
במסך הסכמת המשתמש מוצגים גם פרטי המיתוג, כמו שם המוצר, הלוגו וכתובת ה-URL של דף הבית. אתם שולטים בפרטי המיתוג במסוף Cloud.
כדי להפעיל את מסך ההסכמה של הפרויקט:
- פותחים את הדף Branding במסוף Google Cloud.
- אם מתבקשים, בוחרים פרויקט או יוצרים פרויקט חדש.
- ממלאים את הטופס ולוחצים על שמירה.
בתיבת הדו-שיח הבאה להבעת הסכמה מוצג מה שמשתמש יראה כשבקשה כוללת שילוב של היקפי הרשאות של OAuth 2.0 ו-Google Drive. (תיבת הדו-שיח הגנרית הזו נוצרה באמצעות Google OAuth 2.0 Playground, ולכן היא לא כוללת את פרטי המיתוג שמוגדרים במסוף Cloud).
גישה לשירות
Google וצדדים שלישיים מספקים ספריות שבהן אפשר להשתמש כדי לטפל בהרבה מפרטי ההטמעה של אימות משתמשים וקבלת גישה לממשקי Google API. דוגמאות לכך הן Google Identity Services וספריות הלקוח של Google, שזמינות למגוון פלטפורמות.
אם אתם בוחרים לא להשתמש בספרייה, אתם צריכים לפעול לפי ההוראות בהמשך המסמך הזה, שמתאר את תהליכי בקשות ה-HTTP שעומדים בבסיס הספריות הזמינות.
אימות המשתמש
כדי לאמת את המשתמש, צריך לקבל טוקן של מזהה ולאמת אותו. טוקנים של מזהים הם תכונה סטנדרטית של OpenID Connect, שנועדה לשמש לשיתוף טענות נכונות (assertions) של זהות באינטרנט.
הגישות הנפוצות ביותר לאימות משתמש ולקבלת טוקן של מזהה נקראות "תהליך השרת" ו "התהליך המשתמע". תהליך השרת מאפשר לשרת בק-אנד של אפליקציה לאמת את זהות המשתמש באמצעות דפדפן או מכשיר נייד. משתמשים בזרם הענקת גישה משתמע כשאפליקציה בצד הלקוח (בדרך כלל אפליקציית JavaScript שפועלת בדפדפן) צריכה לגשת ישירות לממשקי API במקום להשתמש בשרת בק-אנד שלה.
במאמר הזה מוסבר איך לבצע את תהליך האימות של המשתמש בצד השרת. זרם הענקת הגישה המשתמע מורכב הרבה יותר, בגלל סיכוני האבטחה שקשורים לטיפול באסימונים ולשימוש בהם בצד הלקוח. אם אתם צריכים להטמיע זרם הענקת גישה משתמע, מומלץ מאוד להשתמש בשירותי Google Identity.
תהליך בשרת
חשוב לוודא שהגדרתם את האפליקציה במסוף Cloud כדי לאפשר לה להשתמש בפרוטוקולים האלה ולאמת את המשתמשים. כשמשתמש מנסה להיכנס באמצעות חשבון Google, אתם צריכים:
- יצירת טוקן מצב למניעת זיוף
- שליחת בקשת אימות ל-Google
- אימות הטוקן של מצב מניעת הזיוף
- החלפת
codeבטוקן גישה ובטוקן של מזהה - קבלת פרטי משתמש מהטוקן של המזהה
- אימות המשתמש
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 הבסיסי ממסמך Discovery באמצעות ערך המטא-נתונים authorization_endpoint. בדיון הבא, ההנחה היא שכתובת ה-URI הבסיסית היא https://accounts.google.com/o/oauth2/v2/auth.
בבקשה בסיסית, צריך לציין את הפרמטרים הבאים:
client_id, שאותו מקבלים מדף הלקוחות במסוף Cloud.-
response_type, שבבקשה בסיסית של הרשאה באמצעות קוד צריך להיותcode. (מידע נוסף זמין בכתובתresponse_type.) -
scope, שבבקשה בסיסית צריך להיותopenid email. (מידע נוסף זמין בכתובתscope). - הערך של
redirect_uriצריך להיות נקודת הקצה (endpoint) של HTTP בשרת שלכם, שתקבל את התגובה מ-Google. הערך חייב להיות זהה לאחד מכתובות ה-URI המורשות להפניה אוטומטית של לקוח OAuth 2.0, שהגדרתם בדף Credentials במסוף Cloud. אם הערך הזה לא תואם ל-URI מורשה, הבקשה תיכשל ותוצג השגיאהredirect_uri_mismatch. - הפרמטר
stateצריך לכלול את הערך של טוקן הסשן הייחודי למניעת זיופים, וגם כל מידע אחר שנדרש כדי לשחזר את ההקשר כשהמשתמש חוזר לאפליקציה, למשל כתובת ה-URL ההתחלתית. (מידע נוסף זמין בכתובתstate). -
nonceהוא ערך אקראי שנוצר על ידי האפליקציה, שמאפשר הגנה מפני הפעלה חוזרת כשהוא קיים. -
login_hintיכול להיות כתובת האימייל של המשתמש או המחרוזתsub, ששווה למזהה Google של המשתמש. אם לא תספקוlogin_hintוהמשתמש מחובר, מסך ההסכמה יכלול בקשה לאישור כדי לשחרר את כתובת האימייל של המשתמש לאפליקציה שלכם. (מידע נוסף זמין בכתובתlogin_hint.) - משתמשים בפרמטר
hdכדי לבצע אופטימיזציה של תהליך OpenID Connect למשתמשים בדומיין מסוים שמשויך לארגון ב-Google Workspace או ב-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//developers.google.com/oauthplayground& 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://developers.google.com/oauthplayground?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
בהתאם ל-RFC 6749, לקוחות חייבים להתעלם מפרמטרים לא מזוהים של תגובה. בשרת, צריך לוודא שהערך של 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 |
מזהה הלקוח שקיבלתם מדף הלקוחות במסוף Cloud, כפי שמתואר בקטע קבלת פרטי כניסה ל-OAuth 2.0. |
client_secret |
סוד הלקוח שמקבלים מדף הלקוחות במסוף Cloud, כמו שמתואר במאמר קבלת פרטי כניסה ל-OAuth 2.0. |
redirect_uri |
כתובת URI מורשית להפניה אוטומטית ל-client_id שצוין בדף Clients במסוף Cloud, כמו שמתואר בקטע הגדרת כתובת 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//developers.google.com/oauthplayground& grant_type=authorization_code
תגובה תקינה לבקשה הזו מכילה את השדות הבאים במערך JSON:
| שדות | |
|---|---|
access_token |
טוקן שאפשר לשלוח ל-Google API. |
expires_in |
משך החיים שנותר לאסימון הגישה, בשניות. |
id_token |
JWT שמכיל פרטי זהות של המשתמש, עם חתימה דיגיטלית של Google. |
scope |
היקפי הגישה שניתנו על ידי access_token, מבוטאים כרשימה של מחרוזות תלויות אותיות רישיות (case-sensitive) שמופרדות ברווחים. |
token_type |
מזהה את סוג הטוקן שהוחזר. בשלב הזה, השדה הזה תמיד מכיל את הערך Bearer.
|
refresh_token |
(אופציונלי)
השדה הזה מופיע רק אם הפרמטר |
5. קבלת פרטי משתמש מהטוקן של המזהה
טוקן של מזהה הוא JWT (טוקן אינטרנט מסוג JSON), כלומר אובייקט JSON שחתום באופן קריפטוגרפי ומקודד ב-Base64. בדרך כלל, חשוב מאוד לאמת את אסימון המזהה לפני שמשתמשים בו, אבל מכיוון שאתם מתקשרים ישירות עם 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 יכולים להכיל את השדות הבאים (שנקראים הצהרות):
| מימוש | הוגדרו | תיאור |
|---|---|---|
aud |
תמיד | הקהל שאמור להשתמש בטוקן של המזהה. הוא חייב להיות אחד ממזהי הלקוח ב-OAuth 2.0 של האפליקציה. |
exp |
תמיד | זמן התפוגה שבו או אחריו אסור לקבל את טוקן של מזהה. מיוצג בזמן של ראשית זמן יוניקס (Unix epoch) (מספר שלם של שניות). |
iat |
תמיד | הזמן שבו הונפק הטוקן של המזהה. מיוצג בזמן של ראשית זמן יוניקס (Unix epoch) (מספר שלם של שניות). |
iss |
תמיד | מזהה המנפיק של מנפיק התגובה. תמיד
https://accounts.google.com או accounts.google.com לטוקנים של מזהי Google. |
sub |
תמיד | מזהה של המשתמש, ייחודי לכל חשבונות Google ולעולם לא נעשה בו שימוש חוזר. לחשבון Google יכולות להיות כמה כתובות אימייל בנקודות זמן שונות, אבל הערך של sub אף פעם לא משתנה. משתמשים ב-sub באפליקציה כמפתח המזהה הייחודי של המשתמש. האורך המקסימלי הוא 255 תווים ב-ASCII, תלוי אותיות רישיות. |
amr |
מערך JSON של מחרוזות שמזהות את שיטות האימות שמשמשות לכניסה לחשבון Google. אם הוא קיים, הוא כולל אחד או יותר מהערכים האפשריים הבאים של [IANA.AMR]:
amr נכללת בבקשת האימות ומופעלת בהגדרות.
|
|
auth_time |
השעה שבה בוצע אימות המשתמש, מספר JSON שמייצג את מספר השניות שחלפו מאז ראשית זמן יוניקס (1 בינואר 1970, 00:00:00 UTC). הערך הזה מופיע אם הטענה auth_time נכללת בבקשת האימות ומופעלת בהגדרות.
|
|
at_hash |
גיבוב (hash) של טוקן גישה. מאמת שטוקן הגישה מקושר לטוקן הזהות. אם הטוקן של המזהה מונפק עם ערך access_token בתהליך השרת, ההצהרה הזו תמיד נכללת. אפשר להשתמש בטענה הנכונה הזו כמנגנון חלופי להגנה מפני מתקפות של זיוף בקשות בין אתרים, אבל אם פועלים לפי שלב 1 ושלב 3, אין צורך לאמת את טוקן הגישה. |
|
azp |
client_id של המציג המורשה. ההצהרה הזו נדרשת רק כאשר הגורם שמבקש את טוקן של מזהה הוא לא אותו קהל של טוקן של מזהה. יכול להיות שזה המצב ב-Google באפליקציות היברידיות, שבהן לאפליקציית אינטרנט ולאפליקציה ל-Android יש client_id שונה של OAuth 2.0, אבל הן משתפות את אותו פרויקט של Google APIs. |
|
email |
זוהי כתובת האימייל של המשתמש. מופיע רק אם כללתם את ההיקף email בבקשה. יכול להיות שהערך של ההצהרה הזו לא ייחודי לחשבון הזה, והוא עשוי להשתנות עם הזמן. לכן, אל תשתמשו בערך הזה כמזהה הראשי לקישור לרשומת המשתמש שלכם. בנוסף, אי אפשר להסתמך על הדומיין של ההצהרה email כדי לזהות משתמשים של ארגונים ב-Google Workspace או ב-Cloud. במקום זאת, צריך להשתמש בהצהרה hd.
|
|
email_verified |
True אם כתובת האימייל של המשתמש אומתה, אחרת False. | |
family_name |
שם המשפחה של המשתמש. יכול להיות שהשדה הזה יופיע כשיש טענת נכוֹנוּת (claim) מסוג name. |
|
given_name |
השם הפרטי של המשתמש. יכול להיות שהשדה הזה יופיע כשיש טענת נכוֹנוּת (claim) מסוג name. |
|
hd |
הדומיין שמשויך לארגון של המשתמש ב-Google Workspace או ב-Cloud. מוצג רק אם המשתמש שייך לארגון ב-Google Cloud. צריך לבדוק את ההצהרה הזו כשמגבילים את הגישה למשאב רק לחברים בדומיינים מסוימים. אם ההצהרה הזו לא קיימת, סימן שהחשבון לא שייך לדומיין שמתארח ב-Google. | |
locale |
הלוקאל של המשתמש, שמיוצג על ידי תג שפה בתקן BCP 47.
יכול להיות שהשדה הזה יופיע כשיש טענת נכוֹנוּת (claim) מסוג name. |
|
name |
השם המלא של המשתמש, בפורמט שניתן להציג. יכול להיות שיופיע במקרים הבאים:
כשהטענות הנכונות של |
|
nonce |
הערך של nonce שסופק על ידי האפליקציה בבקשת האימות.
כדי להגן מפני התקפות שליחה מחדש, צריך להציג את הערך הזה רק פעם אחת. |
|
picture |
כתובת ה-URL של תמונת הפרופיל של המשתמש. יכול להיות שיופיעו במקרים הבאים:
כשיש הצהרות |
|
profile |
כתובת ה-URL של דף הפרופיל של המשתמש. יכול להיות שיופיע במקרים הבאים:
כשיש הצהרות |
6. אימות המשתמש
אחרי שמקבלים את פרטי המשתמש מהטוקן של המזהה, צריך לשלוח שאילתה למסד הנתונים של המשתמשים באפליקציה. אם המשתמש כבר קיים במסד הנתונים, צריך להתחיל סשן באפליקציה בשביל המשתמש הזה, בתנאי שכל דרישות ההתחברות נענו בתגובה מה-API של Google.
אם המשתמש לא קיים במסד הנתונים של המשתמשים, צריך להפנות אותו לתהליך ההרשמה למשתמשים חדשים. יכול להיות שתוכלו לרשום את המשתמש באופן אוטומטי על סמך המידע שאתם מקבלים מ-Google, או לפחות לאכלס מראש הרבה מהשדות שאתם דורשים בטופס ההרשמה. בנוסף למידע שבטוקן של מזהה, אתם יכולים לקבל מידע נוסף על פרופיל המשתמש בנקודות הקצה של פרופיל המשתמש.
נושאים מתקדמים
בקטעים הבאים מוסבר בהרחבה על Google OAuth 2.0 API. המידע הזה מיועד למפתחים עם דרישות מתקדמות בנושא אימות והרשאה.
גישה לממשקי Google API אחרים
אחד מהיתרונות של שימוש ב-OAuth 2.0 לאימות הוא שהאפליקציה יכולה לקבל הרשאה להשתמש בממשקי Google API אחרים בשם המשתמש (כמו YouTube, Google Drive, יומן Google או אנשי קשר) במקביל לאימות המשתמש. כדי לעשות את זה, צריך לכלול את היקפי ההרשאות האחרים שאתם צריכים בבקשת האימות שאתם שולחים ל-Google. לדוגמה, כדי להוסיף את קבוצת הגיל של המשתמש לבקשת האימות, צריך להעביר פרמטר היקף של openid email https://www.googleapis.com/auth/profile.agerange.read. המשתמש מקבל בקשה מתאימה במסך ההסכמה.
אסימון הגישה שתקבלו מ-Google יאפשר לאפליקציה לגשת לכל ממשקי ה-API שקשורים להיקפי הגישה שביקשתם וקיבלתם.
אסימוני רענון
בבקשה לגישה ל-API, אתם יכולים לבקש שיוחזר טוקן רענון במהלך החלפת code. טוקן רענון מספק לאפליקציה גישה רציפה לממשקי Google API כשהמשתמש לא נמצא באפליקציה. כדי לבקש טוקן רענון, מוסיפים את הפרמטר access_type לערך offline בבקשת האימות.
שיקולים:
- חשוב לשמור את טוקן הרענון באופן בטוח וקבוע, כי אפשר לקבל טוקן רענון רק בפעם הראשונה שמבצעים את תהליך החלפת הקוד.
- יש מגבלות על מספר טוקני הרענון שמונפקים: מגבלה אחת לכל שילוב של לקוח/משתמש, ומגבלה נוספת לכל משתמש בכל הלקוחות. אם האפליקציה מבקשת יותר מדי טוקנים לרענון, היא עלולה להגיע למגבלות האלה, ובמקרה כזה טוקנים ישנים יותר לרענון יפסיקו לפעול.
מידע נוסף זמין במאמר רענון של טוקן גישה (גישה אופליין).
בקשה לקבלת הסכמה מחדש
כדי לבקש מהמשתמש לאשר מחדש את האפליקציה, מגדירים את הפרמטר prompt לערך consent בבקשת האימות. כשכוללים את prompt=consent, מסך ההסכמה מוצג בכל פעם שהאפליקציה מבקשת הרשאה להיקפי גישה, גם אם כל ההיקפים כבר הוענקו לפרויקט Google APIs. לכן, כדאי לכלול את prompt=consent רק כשצריך.
למידע נוסף על הפרמטר prompt, אפשר לעיין בקטע prompt בטבלה פרמטרים של URI לאימות.
פרמטרים של URI לאימות
בטבלה הבאה מפורטים תיאורים מלאים יותר של הפרמטרים שמתקבלים על ידי ממשק ה-API לאימות OAuth 2.0 של Google.
| פרמטר | חובה | תיאור | ||||||
|---|---|---|---|---|---|---|---|---|
client_id |
(חובה) | מחרוזת מזהה הלקוח שקיבלתם מדף הלקוחות במסוף Cloud, כפי שמתואר במאמר קבלת פרטי כניסה ל-OAuth 2.0. | ||||||
nonce |
(חובה) | ערך אקראי שנוצר על ידי האפליקציה ומאפשר הגנה מפני הפעלה חוזרת. | ||||||
response_type |
(חובה) | אם הערך הוא code, מופעל תהליך בסיסי של הרשאה באמצעות קוד, שדורש POST לנקודת הקצה של האסימון כדי לקבל את האסימונים. אם הערך הוא token id_token או id_token token, מופעל זרם הענקת גישה משתמע, שמחייב שימוש ב-JavaScript בכתובת ה-URI להפניה אוטומטית כדי לאחזר טוקנים ממזהה ה-URI #fragment. |
||||||
redirect_uri |
(חובה) | קובע לאן התשובה תישלח. הערך של הפרמטר הזה חייב להתאים בדיוק לאחד מערכי ההפניה המורשים שהגדרתם בדף הלקוחות במסוף Cloud (כולל הסכימה HTTP או HTTPS, אותיות רישיות ולוכסן בסוף, אם יש). | ||||||
scope |
(חובה) | הפרמטר scope חייב להתחיל בערך אם ערך ההיקף אם ערך ההיקף בנוסף להיקפי ההרשאות הספציפיים ל-OpenID, הארגומנט של היקף ההרשאות יכול לכלול גם ערכים אחרים של היקפי הרשאות. כל ערכי ההיקף חייבים להיות מופרדים ברווחים. לדוגמה, אם אתם רוצים גישה לכל קובץ ב-Google Drive של המשתמש, פרמטר ההיקף יכול להיות למידע על היקפי ההרשאות הזמינים, קראו את המאמר היקפי ההרשאות של OAuth 2.0 ל-Google APIs או את המסמכים של Google API שבו אתם רוצים להשתמש. |
||||||
state |
(אופציונלי, אבל מומלץ מאוד) | מחרוזת אטומה שעוברת הלוך ושוב בפרוטוקול. כלומר, היא מוחזרת כפרמטר URI בזרם הענקת הגישה הבסיסי, ובמזהה ה-URI השדה |
||||||
access_type |
(אופציונלי) | הערכים המותרים הם offline ו-online. ההשפעה מתועדת בקטע גישה אופליין. אם מתבצעת בקשה לטוקן גישה, הלקוח לא מקבל טוקן רענון אלא אם צוין הערך offline. |
||||||
claims |
(אופציונלי) |
הפרמטר claims משמש כדי לציין שדה אופציונלי אחד או יותר שצריך לכלול בנקודת הקצה של פרטי המשתמש או בסוגי התגובות של טוקן המזהה של בקשת האימות. הערך הוא אובייקט JSON שמכיל את סוג התגובה ואת ההצהרות המבוקשות. השרתים של Google מקבלים את בקשות התביעה הבאות:
|
||||||
display |
(אופציונלי) | ערך מחרוזת ASCII שמציין איך שרת ההרשאות מציג את דפי ממשק המשתמש של האימות וההסכמה. הערכים הבאים מצוינים ומתקבלים על ידי שרתי Google, אבל אין להם השפעה על ההתנהגות של תהליך הפרוטוקול: page, popup, touch ו-wap. |
||||||
hd |
(אופציונלי) | לייעל את תהליך ההתחברות לחשבונות שבבעלות ארגון ב-Google Cloud. אם תכללו את הדומיין של הארגון ב-Google Cloud (לדוגמה, mycollege.edu), תוכלו לציין שצריך לבצע אופטימיזציה של ממשק המשתמש לבחירת חשבון בשביל חשבונות בדומיין הזה. כדי לבצע אופטימיזציה לחשבונות של ארגונים ב-Google Cloud באופן כללי, במקום רק לדומיין אחד של ארגון ב-Google Cloud, צריך להגדיר ערך של כוכבית ( אל תסתמכו על האופטימיזציה הזו של ממשק המשתמש כדי לקבוע למי תהיה גישה לאפליקציה, כי אפשר לשנות בקשות בצד הלקוח. חשוב לוודא שערך ההצהרה |
||||||
include_granted_scopes |
(אופציונלי) | אם הפרמטר הזה מסופק עם הערך true ובקשת ההרשאה אושרה, ההרשאה תכלול את כל ההרשאות הקודמות שניתנו לשילוב הזה של משתמש/אפליקציה להיקפים אחרים. מידע נוסף זמין במאמר
הרשאה מצטברת.
שימו לב שאי אפשר לבצע הרשאה מצטברת בתהליך של אפליקציה להתקנה. |
||||||
login_hint |
(אופציונלי) | כשהאפליקציה יודעת איזה משתמש היא מנסה לאמת, היא יכולה לספק את הפרמטר הזה כרמז לשרת האימות (AS). העברת הרמז הזה מבטלת את בורר החשבונות וממלאת מראש את תיבת האימייל בטופס הכניסה, או בוחרת את הסשן המתאים (אם המשתמש משתמש בכניסה עם מספר חשבונות). כך אפשר להימנע מבעיות שמתרחשות אם האפליקציה מתחברת לחשבון המשתמש הלא נכון.
הערך יכול להיות כתובת אימייל או המחרוזת sub, ששווה למזהה Google של המשתמש. |
||||||
prompt |
(אופציונלי) | רשימה של ערכי מחרוזת מופרדים ברווחים שמציינת אם שרת ההרשאות מבקש מהמשתמש לבצע אימות מחדש ולהביע הסכמה. הערכים האפשריים הם:
אם לא צוין ערך והמשתמש לא אישר בעבר את הגישה, יוצג למשתמש מסך הסכמה. |
||||||
hl |
(אופציונלי) | תג שפה בתקן BCP 47 שמשמש לציון שפת התצוגה של מסכי הכניסה, בחירת החשבון וההסכמה. אם לא מציינים את הפרמטר הזה, השפה שמוגדרת כברירת מחדל היא השפה שמוגדרת בחשבון Google או בדפדפן של המשתמש. לדוגמה, כדי לבקש את ממשק המשתמש באנגלית בריטית, מגדירים את הפרמטר לערך en-GB.
|
||||||
אימות של טוקן של מזהה
אתם צריכים לאמת את כל הטוקנים של המזהים בשרת, אלא אם אתם יודעים שהם הגיעו ישירות מ-Google. לדוגמה, השרת חייב לאמת את האותנטיות של כל טוקן של מזהה שהוא מקבל מאפליקציות הלקוח.
אלה כמה מצבים נפוצים שבהם כדאי לשלוח טוקנים של מזהים לשרת:
- שליחת טוקנים של מזהים עם בקשות שצריך לאמת. הטוקנים של המזהים מציינים את המשתמש הספציפי ששלח את הבקשה, ואת הלקוח שהטוקן של המזהה הוענק לו.
טוקנים של מזהים הם רגישים, ואם הם נחשפים, אפשר להשתמש בהם לרעה. אתם צריכים לוודא שהאסימונים האלה מטופלים בצורה מאובטחת, על ידי העברה שלהם רק באמצעות HTTPS ורק באמצעות נתוני POST או בתוך request headers. אם אתם שומרים טוקנים של מזהים בשרת, אתם צריכים לשמור אותם באופן מאובטח.
אחד היתרונות של טוקנים של מזהים הוא שאפשר להעביר אותם בין רכיבים שונים של האפליקציה. הרכיבים האלה יכולים להשתמש בטוקן של מזהה כמנגנון אימות קל משקל לאימות האפליקציה והמשתמש. אבל לפני שתוכלו להשתמש במידע שבטוקן של מזהה או להסתמך עליו כהצהרה שהמשתמש אומת, אתם חייבים לאמת אותו.
אימות של טוקן של מזהה דורש כמה שלבים:
- מוודאים שהטוקן של המזהה חתום כראוי על ידי המנפיק. האסימונים ש-Google מנפיקה נחתמים באמצעות אחד מהאישורים שנמצאים ב-URI שצוין בערך המטא-נתונים
jwks_uriשל מסמך Discovery. - מוודאים שהערך של ההצהרה
issבטוקן של מזהה שווה ל-https://accounts.google.comאו ל-accounts.google.com. - מוודאים שהערך של ההצהרה
audבטוקן של מזהה זהה למזהה הלקוח של האפליקציה. - מוודאים שמועד התפוגה (הצהרת
exp) של טוקן של מזהה לא עבר. - אם ציינתם בבקשה ערך של פרמטר hd, ודאו שבטוקן המזהה יש הצהרת
hdשתואמת לדומיין מקובל שמשויך לארגון ב-Google Cloud.
שלבים 2 עד 5 כוללים רק השוואות של מחרוזות ותאריכים, שהן די פשוטות, ולכן לא נפרט אותן כאן.
השלב הראשון מורכב יותר, וכולל בדיקת חתימה קריפטוגרפית.
למטרות ניפוי באגים, אתם יכולים להשתמש בנקודת הקצה tokeninfo של Google כדי להשוות אותה לעיבוד המקומי שמוטמע בשרת או במכשיר שלכם. נניח שהערך של טוקן המזהה הוא XYZ123. לאחר מכן, תבטלו את ההפניה ל-URI
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123.
אם החתימה של האסימון תקינה, התגובה תהיה המטען הייעודי של ה-JWT בצורת אובייקט JSON מפוענח.
נקודת הקצה tokeninfo שימושית לניפוי באגים, אבל למטרות ייצור, צריך לאחזר את המפתחות הציבוריים של Google מנקודת הקצה של המפתחות ולבצע את האימות באופן מקומי. צריך לאחזר את כתובת ה-URI של המפתחות ממסמך Discovery באמצעות ערך המטא-נתונים jwks_uri. יכול להיות שיופעלו הגבלות קצב על בקשות לנקודת הקצה (endpoint) לניפוי באגים, או שהן יגרמו לשגיאות לסירוגין.
Google משנה את המפתחות הציבוריים שלה לעיתים רחוקות, לכן אתם יכולים לשמור אותם במטמון באמצעות הוראות המטמון של תגובת ה-HTTP. ברוב המקרים, תוכלו לבצע אימות מקומי בצורה יעילה יותר מאשר באמצעות נקודת הקצה tokeninfo. כדי לבצע את האימות הזה, צריך לאחזר ולנתח אישורים, ולבצע את הקריאות הקריפטוגרפיות המתאימות כדי לבדוק את החתימה. למרבה המזל, יש ספריות שעברו ניפוי באגים וזמינות במגוון רחב של שפות כדי לבצע את הפעולה הזו (ראו jwt.io).
קבלת פרטים מפרופיל המשתמש
כדי לקבל פרטים נוספים על פרופיל המשתמש, אתם יכולים להשתמש בטוקן הגישה (שהאפליקציה מקבלת במהלך תהליך האימות) ובתקן OpenID Connect:
כדי לעמוד בדרישות של OpenID, צריך לכלול את ערכי ההיקף
openid profileבבקשת האימות.אם רוצים שכתובת האימייל של המשתמש תיכלל, אפשר לציין ערך היקף נוסף של
email. כדי לציין גם אתprofileוגם אתemail, אפשר לכלול את הפרמטר הבא ב-URI של בקשת האימות:scope=openid%20profile%20emailמוסיפים את טוקן הגישה לכותרת ההרשאה ושולחים בקשת HTTPS
GETלנקודת הקצה userinfo, שאותה צריך לאחזר ממסמך Discovery באמצעות ערך המטא-נתוניםuserinfo_endpoint. התגובה של userinfo כוללת מידע על המשתמש, כמו שמתואר ב-OpenID Connect Standard Claimsובערך המטא-נתוניםclaims_supportedשל מסמך Discovery. המשתמשים או הארגונים שלהם יכולים לבחור אם לספק או להסתיר שדות מסוימים, כך שיכול להיות שלא תקבלו מידע בכל שדה בהיקפי הגישה המורשים שלכם.
מסמך Discovery
פרוטוקול OpenID Connect דורש שימוש במספר נקודות קצה (endpoints) כדי לאמת משתמשים ולבקש משאבים, כולל אסימונים, פרטי משתמשים ומפתחות ציבוריים.
כדי לפשט את ההטמעות ולהגביר את הגמישות, 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 (המשמעויות שלהם מפורטות במסמך הזה). הערכים הם להמחשה בלבד ועשויים להשתנות, למרות שהם מועתקים מגרסה עדכנית של מסמך Discovery של Google:
{ "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 באמצעות שילוב עם מסגרות פופולריות:
- ספריית הלקוח של Google APIs ל-Java
- ספריית הלקוח של Google APIs ל-Python
- ספריית הלקוח של Google APIs ל- .NET
- ספריית הלקוח של Google APIs ל-Ruby
- ספריית הלקוח של Google APIs ל-PHP
- ספריית OAuth 2.0 ל-Google Web Toolkit
- בקרי OAuth 2.0 של Google Toolbox for Mac
תאימות ל-OpenID Connect
מערכת האימות OAuth 2.0 של Google תומכת בתכונות הנדרשות של מפרט OpenID Connect Core. כל לקוח שמיועד לעבוד עם OpenID Connect אמור לפעול עם השירות הזה (למעט אובייקט הבקשה של OpenID).
