אפשר להשתמש בממשקי ה-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 אחרים.
במסך הסכמת המשתמש מוצג גם מידע על המיתוג, כמו שם המוצר, הלוגו וכתובת דף הבית. אתם יכולים לשלוט בפרטי המיתוג במסוף 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 Services.
תהליך בשרת
חשוב לוודא שהגדרתם את האפליקציה במסוף 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צריכה להיות נקודת הקצה של 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 שמייצג את מספר השניות שחלפו מאז ראשית זמן יוניקס (Unix epoch) (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 משמש כדי לציין שדה אופציונלי אחד או יותר שצריך לכלול בנקודת הקצה userinfo או בסוגי התגובות של טוקן המזהה של בקשת האימות. הערך הוא אובייקט 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 שמשמש לציון שפת התצוגה של מסכי הכניסה, Account Chooser ומסכי ההסכמה. אם לא מציינים את הפרמטר הזה, השפה שמוגדרת כברירת מחדל היא השפה שמוגדרת בחשבון Google או בדפדפן של המשתמש. לדוגמה, כדי לבקש את ממשק המשתמש באנגלית בריטית, מגדירים את הפרמטר לערך en-GB.
|
||||||
אימות של טוקן של מזהה
צריך לאמת את כל אסימוני המזהה בשרת, אלא אם ידוע שהם הגיעו ישירות מ-Google. לדוגמה, השרת צריך לאמת את האותנטיות של כל טוקן של מזהה שהוא מקבל מאפליקציות הלקוח.
אלה מצבים נפוצים שבהם אתם יכולים לשלוח אסימוני מזהה לשרת:
- שליחת טוקנים של מזהים עם בקשות שצריך לאמת. האסימונים המזהים מציינים את המשתמש הספציפי ששלח את הבקשה, ואת הלקוח שקיבל את האסימון המזהה.
טוקנים של מזהים הם רגישים, ואם הם נחשפים, אפשר להשתמש בהם לרעה. אתם צריכים לוודא שהטיפול בטוקנים האלה מתבצע באופן מאובטח, על ידי העברה שלהם רק באמצעות HTTPS ורק באמצעות נתוני POST או בתוך request headers. אם אתם שומרים טוקנים של מזהים בשרת, אתם צריכים לשמור אותם בצורה מאובטחת.
אחד היתרונות של טוקנים של מזהים הוא שאפשר להעביר אותם בין רכיבים שונים של האפליקציה. הרכיבים האלה יכולים להשתמש בטוקן של מזהה כמנגנון אימות פשוט שמאמת את האפליקציה ואת המשתמש. אבל לפני שאתם יכולים להשתמש במידע שבטוקן של מזהה או להסתמך עליו כטענת נכוֹנוּת (assertion) שהמשתמש אומת, אתם חייבים לאמת אותו.
אימות של טוקן של מזהה דורש כמה שלבים:
- מוודאים שהטוקן של המזהה חתום כראוי על ידי המנפיק. האסימונים ש-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. אם החתימה של האסימון תקינה, התגובה תהיה המטען הייעודי (payload) של ה-JWT בצורת אובייקט JSON מפוענח.
נקודת הקצה tokeninfo שימושית לניפוי באגים, אבל למטרות ייצור, צריך לאחזר את המפתחות הציבוריים של Google מנקודת הקצה של המפתחות ולבצע את האימות באופן מקומי. צריך לאחזר את ה-URI של המפתחות ממסמך Discovery באמצעות ערך המטא-נתונים jwks_uri. יכול להיות שיהיו הגבלות על בקשות לנקודת הקצה לניפוי באגים, או שהן יהיו כפופות לשגיאות לסירוגין.
Google משנה את המפתחות הציבוריים שלה רק לעיתים רחוקות, לכן אתם יכולים לשמור אותם במטמון באמצעות הוראות המטמון של תגובת ה-HTTP. ברוב המקרים, אתם יכולים לבצע אימות מקומי בצורה יעילה הרבה יותר מאשר באמצעות נקודת הקצה tokeninfo. כדי לבצע את האימות הזה, צריך לאחזר ולנתח אישורים, ולבצע את הקריאות הקריפטוגרפיות המתאימות כדי לבדוק את החתימה. למרבה המזל, יש ספריות שעברו ניפוי באגים וזמינות במגוון רחב של שפות כדי לבצע את הפעולה הזו (ראו jwt.io).
קבלת פרטים מפרופיל המשתמש
כדי לקבל פרטי פרופיל נוספים על המשתמש, אתם יכולים להשתמש בטוקן הגישה (שהאפליקציה מקבלת במהלך תהליך האימות) ובתקן OpenID Connect:
כדי לעמוד בדרישות של OpenID, צריך לכלול את ערכי ההיקף
openid profileבבקשת האימות.אם רוצים שכתובת האימייל של המשתמש תיכלל, אפשר לציין ערך היקף נוסף של
email. כדי לציין גם אתprofileוגם אתemail, אפשר לכלול את הפרמטר הבא ב-URI של בקשת האימות:scope=openid%20profile%20email
- מוסיפים את אסימון הגישה לכותרת ההרשאה ושולחים בקשת HTTPS
GETלנקודת הקצה של פרטי המשתמש, שאותה צריך לאחזר ממסמך 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:
תאימות ל-OpenID Connect
מערכת האימות OAuth 2.0 של Google תומכת בתכונות הנדרשות של מפרט OpenID Connect Core. כל לקוח שמיועד לעבוד עם OpenID Connect אמור לפעול עם השירות הזה (למעט אובייקט הבקשה של OpenID).
