אפשר להשתמש בממשקי ה-API של Google מסוג OAuth 2.0 גם לאימות וגם להרשאה. במסמך הזה מתוארת הטמעת OAuth 2.0 שלנו לאימות, שתואמת למפרט של OpenID Connect ומאושרת על ידי OpenID. המסמכים שמופיעים במאמר שימוש ב-OAuth 2.0 לגישה ל-Google APIs רלוונטיים גם לשירות הזה. כדי לבדוק את הפרוטוקול הזה באופן אינטראקטיבי, מומלץ להיכנס אל מגרש המשחקים של Google OAuth 2.0. כדי לקבל עזרה ב-Stack Overflow, צריך לתייג את השאלות שלכם בתג 'google-oauth'.
הגדרת OAuth 2.0
כדי שהאפליקציה שלכם תוכל להשתמש במערכת האימות של Google מסוג OAuth 2.0 לכניסת משתמשים, עליכם להגדיר פרטי כניסה ל-OAuth 2.0 ב- Google API Console , להגדיר URI להפניה אוטומטית (redirect) ולשנות (אופציונלי) את פרטי המיתוג שיוצגו למשתמשים במסך ההסכמה שלהם. אפשר גם להשתמש ב- API Console כדי ליצור חשבון שירות, להפעיל חיוב, להגדיר סינון ולבצע משימות אחרות. פרטים נוספים זמינים במאמר העזרה של Google API Console.
קבלת פרטי כניסה ל-OAuth 2.0
כדי לאמת משתמשים ולקבל גישה לממשקי ה-API של Google, נדרשים פרטי כניסה של OAuth 2.0, כולל מזהה לקוח וסוד לקוח.
כדי להציג את מזהה הלקוח וסוד הלקוח עבור אישור נתון OAuth 2.0, לחץ על הטקסט הבא: בחר אישור . בחלון שנפתח בחר את הפרוייקט שלך ואת האישור שאתה רוצה ולחץ על תצוגה .
לחלופין, צפה בזיהוי הלקוח ובסוד הלקוח שלך מדף האישורים ב API Console :
- Go to the Credentials page.
- לחץ על שם האישור שלך או על סמל העיפרון ( create ). קוד זיהוי הלקוח וסודך נמצאים בראש העמוד.
הגדרת URI להפניה אוטומטית
ה-URI להפניה אוטומטית שהגדרתם ב- API Console קובע לאן Google שולחת תשובות לבקשות האימות.
כדי ליצור, להציג או לערוך את כתובות ה- URI להפניה מחדש עבור אישור נתון OAuth 2.0, בצע את הפעולות הבאות:
- Go to the Credentials page.
- בקטע מזהי לקוח OAuth 2.0 בדף, לחץ על אישור.
- הצגה או עריכה של קבצי ה- URI המפנים מחדש.
אם אין קטע מזהי לקוח של OAuth 2.0 בדף האישורים, לפרויקט שלך אין אישורי OAuth. כדי ליצור אחת, לחץ על צור אישורים .
התאמה אישית של מסך ההסכמה של המשתמש
חוויית האימות של OAuth 2.0 כוללת מסך הסכמה שבו מתוארים המידע שהמשתמש משחרר והמונחים הרלוונטיים. לדוגמה, כשהמשתמש נכנס לחשבון, יכול להיות שהוא יתבקש לתת לאפליקציה גישה לכתובת האימייל ולפרטי החשבון הבסיסיים שלו. מבקשים גישה למידע הזה באמצעות הפרמטר scope
, שהאפליקציה כוללת בבקשת האימות שלה. אפשר גם להשתמש בהיקפי הרשאות כדי לבקש גישה לממשקי API אחרים של Google.
במסך הסכמת המשתמש מוצגים גם פרטי מיתוג, כמו שם המוצר, הלוגו וכתובת ה-URL של דף הבית. אתם שולטים בפרטי המיתוג ב- API Console.
כדי לאפשר את מסך ההסכמה של הפרויקט שלך:
- פתח את Consent Screen page ב- Google API Console .
- If prompted, select a project, or create a new one.
- מלא את הטופס ולחץ על שמור .
בתיבת הדו-שיח הבאה להבעת הסכמה מוצג מה שהמשתמש יראה כשבקשה מכילה שילוב של היקפי הרשאות של OAuth 2.0 ושל Google Drive. (תיבת הדו-שיח הגנרית הזו נוצרה באמצעות Google OAuth 2.0 Playground, ולכן היא לא כוללת פרטי מיתוג שייקבעו ב- API Console).
גישה לשירות
Google וצדדים שלישיים מספקים ספריות שאפשר להשתמש בהן כדי לטפל בחלק גדול מפרטי ההטמעה של אימות משתמשים וקבלת גישה לממשקי Google API. דוגמאות לכך הן Google Identity Services וספריות הלקוח של Google, שזמינות למגוון פלטפורמות.
אם בוחרים לא להשתמש בספרייה, פועלים לפי ההוראות שבחלקים הבאים של המסמך, שמתארים את תהליכי הבקשות של HTTP שמהווים את הבסיס לספריות הזמינות.
אימות המשתמש
אימות המשתמש כרוך בקבלת אסימון מזהה ואימות שלו. אסימונים מזהים הם תכונה סטנדרטית של OpenID Connect שנועדה לשימוש בשיתוף טענות נכוֹנוּת (assertions) של זהות באינטרנט.
הגישות הנפוצות ביותר לאימות משתמש ולקבלת אסימון מזהה נקראות 'זרם שרת' ו'זרם משתמע'. תהליך האימות בשרת מאפשר לשרת הקצה של האפליקציה לאמת את הזהות של המשתמש באמצעות דפדפן או מכשיר נייד. התהליך המשתמעים משמש כשאפליקציה בצד הלקוח (בדרך כלל אפליקציית JavaScript שפועלת בדפדפן) צריכה לגשת לממשקי API ישירות במקום דרך שרת הקצה שלה.
במאמר הזה נתאר איך לבצע את תהליך האימות של המשתמש בשרת. התהליך המשתמע מורכב יותר באופן משמעותי בגלל סיכוני אבטחה שקשורים לטיפול באסימונים ולשימוש בהם בצד הלקוח. אם אתם צריכים להטמיע תהליך סמוי, מומלץ מאוד להשתמש ב-Google Identity Services.
תהליך השרת
חשוב להגדיר את האפליקציה ב- API Console כדי לאפשר לה להשתמש בפרוטוקולים האלה ולאמת את המשתמשים. כשמשתמש מנסה להתחבר באמצעות חשבון Google, צריך:
- יצירת טוקן מצב למניעת זיוף
- שליחת בקשת אימות ל-Google
- אימות של אסימון המצב למניעת זיוף
- המרת
code
לאסימון גישה ולאסימון מזהה - איך מקבלים את פרטי המשתמש מהאסימון המזהה
- אימות המשתמש
1. יצירת טוקן מצב למניעת זיוף
עליכם להגן על אבטחת המשתמשים שלכם על ידי מניעת התקפות של זיוף בקשות. השלב הראשון הוא יצירת אסימון סשן ייחודי שמכיל את המצב בין האפליקציה לבין הלקוח של המשתמש. בשלב מאוחר יותר, תוכלו להתאים את אסימון הסשן הייחודי הזה לתשובת האימות שתוחזר על ידי שירות הכניסה של Google OAuth, כדי לוודא שהבקשה נשלחה על ידי המשתמש ולא על ידי תוקף זדוני. האסימונים האלה נקראים לעיתים קרובות אסימונים של זיוף בקשות בין אתרים (CSRF).
אפשרות טובה לטוקן מצב היא מחרוזת של כ-30 תווים שנוצרה באמצעות מחולל מספרים אקראיים באיכות גבוהה. אפשרות נוספת היא גיבוב שנוצר על ידי חתימה על חלק ממשתני מצב הסשן באמצעות מפתח שנשמר בסוד בקצה העורפי.
הקוד הבא מדגים יצירת אסימוני סשן ייחודיים.
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
השלב הבא הוא ליצור בקשת GET
ב-HTTPS עם פרמטרים מתאימים של 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 Console Credentials page. אם הערך הזה לא תואם ל-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//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
, שהוא קוד הרשאה חד-פעמי שהשרת יכול להמיר לאסימון גישה ולאסימון מזהה. השרת מבצע את ההחלפה הזו על ידי שליחת בקשת POST
ב-HTTPS. הבקשה 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 |
(אופציונלי)
השדה הזה מופיע רק אם הפרמטר |
5. אחזור פרטי משתמשים מהאסימון המזהה
אסימון מזהה הוא JWT (JSON Web Token), כלומר אובייקט JSON חתום באופן קריפטוגרפי בקידוד Base64. בדרך כלל, חשוב מאוד לאמת אסימון מזהה לפני שמשתמשים בו, אבל מכיוון שאתם מתקשרים ישירות עם Google דרך ערוץ HTTPS ללא מתווך, ומשתמשים בסוד הלקוח כדי לאמת את עצמכם בפני Google, אתם יכולים להיות בטוחים שהאסימון שאתם מקבלים באמת מגיע מ-Google ותקף. אם השרת מעביר את אסימון הזהות לרכיבים אחרים באפליקציה, חשוב מאוד שהרכיבים האחרים יאמתו את האסימון לפני השימוש בו.
מאחר שרוב ספריות ה-API משלבות את האימות עם הפענוח של הערכים בקידוד base64url ופירוק ה-JSON שבתוכם, סביר להניח שתצטרכו לאמת את האסימון בכל מקרה כשתיגשו לטענות הנכונות באסימון המזהה.
עומס העבודה של אסימון מזהה
אסימון מזהה הוא אובייקט 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 |
תמיד | מועד התפוגה, שבו אסור לקבל את אסימון המזהה או אחריו. מיוצג בזמן יוניקס (שניות שלמים). |
iat |
תמיד | השעה שבה הונפק האסימון המזהה. מיוצג בזמן יוניקס (שניות שלמות). |
iss |
תמיד | מזהה המנפיק של המנפיק של התשובה. תמיד https://accounts.google.com או accounts.google.com לאסימונים מזהים של Google. |
sub |
תמיד | מזהה של המשתמש, ייחודי לכל חשבונות Google ושאף פעם לא נעשה בו שימוש חוזר. לחשבון Google יכולות להיות כמה כתובות אימייל בנקודות זמן שונות, אבל הערך של sub אף פעם לא משתנה. משתמשים ב-sub באפליקציה בתור המפתח של המזהה הייחודי של המשתמש. האורך המקסימלי הוא 255 תווים של ASCII שתלוי אותיות רישיות. |
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 |
השמות הפרטיים או שמות המשפחה של המשתמש. יכול להיות שהשדה הזה יופיע אם יש תלונה מסוג name . |
|
given_name |
השמות הפרטיים של המשתמש. יכול להיות שהשדה הזה יופיע אם יש תלונה מסוג name . |
|
hd |
הדומיין שמשויך לארגון של המשתמש ב-Google Workspace או ב-Cloud. השדה הזה מופיע רק אם המשתמש שייך לארגון ב-Google Cloud. צריך לבדוק את ההצהרה הזו כשמגבילים את הגישה למשאב רק לחברים בדומיינים מסוימים. אם ההצהרה הזו לא מופיעה, המשמעות היא שהחשבון לא שייך לדומיין שמתארח ב-Google. | |
locale |
האזור הגיאוגרפי והשפה של המשתמש, שמיוצגים על ידי תג שפה מסוג BCP 47.
יכול להיות שהשדה הזה יופיע אם יש תלונה מסוג name . |
|
name |
השם המלא של המשתמש, בצורה שניתנת להצגה. יכול להיות שהם יסופקו במקרים הבאים:
כשיש הצהרות |
|
nonce |
הערך של nonce שסופק על ידי האפליקציה בבקשת האימות.
כדי לאכוף הגנה מפני התקפות שחזור, צריך לוודא שהאסימון מוצג רק פעם אחת. |
|
picture |
כתובת ה-URL של תמונת הפרופיל של המשתמש. יכול להיות שהם יסופקו במקרים הבאים:
כשיש הצהרות |
|
profile |
כתובת ה-URL של דף הפרופיל של המשתמש. יכול להיות שהם יסופקו במקרים הבאים:
כשיש הצהרות |
6. אימות המשתמש
אחרי שמקבלים את פרטי המשתמש מאסימון המזהה, צריך לשלוח שאילתה למסד הנתונים של המשתמשים באפליקציה. אם המשתמש כבר קיים במסד הנתונים, צריך להתחיל סשן של האפליקציה עבור המשתמש הזה אם התשובה מ-Google API עומדת בכל דרישות הכניסה.
אם המשתמש לא קיים במסד הנתונים של המשתמשים, צריך להפנות אותו לתהליך ההרשמה של משתמשים חדשים. יכול להיות שתוכלו לרשום את המשתמש באופן אוטומטי על סמך המידע שאתם מקבלים מ-Google, או לפחות לאכלס מראש הרבה מהשדות הנדרשים בטופס ההרשמה. בנוסף למידע שמופיע באסימון המזהה, אפשר לקבל פרטים נוספים על פרופיל המשתמש בנקודות הקצה של פרופיל המשתמש.
נושאים מתקדמים
בקטעים הבאים מוסבר בפירוט על Google OAuth 2.0 API. המידע הזה מיועד למפתחים עם דרישות מתקדמות בנוגע לאימות ולהרשאה.
גישה לממשקי API אחרים של Google
אחד מהיתרונות של שימוש ב-OAuth 2.0 לאימות הוא שהאפליקציה יכולה לקבל הרשאה להשתמש בממשקי API אחרים של Google בשם המשתמש (כמו YouTube, Google Drive, יומן או אנשי קשר) בזמן שאתם מאמתים את המשתמש. כדי לעשות זאת, צריך לכלול את ההיקפים האחרים הנדרשים בבקשת האימות ששולחים ל-Google. לדוגמה, כדי להוסיף את קבוצת הגיל של המשתמש לבקשת האימות, מעבירים את הפרמטר openid email https://www.googleapis.com/auth/profile.agerange.read
. המשתמש מקבל בקשה מתאימה במסך ההסכמה. אסימון הגישה שתקבלו מ-Google יאפשר לכם לגשת לכל ממשקי ה-API שקשורים להיקפי הגישה שביקשתם וקיבלתם.
אסימוני רענון
בבקשה לגישה ל-API, אפשר לבקש שיוחזר טוקן רענון במהלך ההחלפה של code
. אסימון רענון מספק לאפליקציה גישה רציפה לממשקי Google APIs בזמן שהמשתמש לא נמצא באפליקציה. כדי לבקש אסימון רענון, צריך להגדיר את הערך offline
לפרמטר access_type
בבקשת האימות.
שיקולים:
- חשוב לאחסן את אסימון הרענון באופן מאובטח וקבוע, כי אפשר לקבל אסימון רענון רק בפעם הראשונה שמבצעים את תהליך החלפת הקוד.
- יש מגבלות על מספר אסימוני הרענון שמונפקים: מגבלה אחת לכל שילוב של לקוח/משתמש, ומגבלה נוספת לכל משתמש בכל הלקוחות. אם האפליקציה שלכם מבקשת יותר מדי אסימוני רענון, היא עלולה להגיע למגבלות האלה. במקרה כזה, אסימוני רענון ישנים יותר יפסיקו לפעול.
למידע נוסף, ראו רענון של אסימון גישה (גישה אופליין).
הצגת בקשה להבעת הסכמה מחדש
כדי לבקש מהמשתמש להעניק הרשאה מחדש לאפליקציה, מגדירים את הפרמטר prompt
לערך consent
בבקשת האימות. כשהאפשרות prompt=consent
כלולה, מסך ההסכמה מוצג בכל פעם שהאפליקציה מבקשת הרשאה להיקפי גישה, גם אם כל ההיקפים הוקצו בעבר לפרויקט Google APIs. לכן, מומלץ לכלול את prompt=consent
רק במקרים שבהם הדבר הכרחי.
מידע נוסף על הפרמטר prompt
זמין בקטע prompt
בטבלה פרמטרים של URI לאימות.
פרמטרים של URI לאימות
בטבלה הבאה מפורטים תיאורים מלאים יותר של הפרמטרים שמקבל API האימות של OAuth 2.0 של Google.
פרמטר | חובה | תיאור |
---|---|---|
client_id |
(נדרש) | מחרוזת מזהה הלקוח שמקבלים מ- API Console Credentials page, כפי שמתואר בקטע קבלת פרטי כניסה ל-OAuth 2.0. |
nonce |
(נדרש) | ערך אקראי שנוצר על ידי האפליקציה ומאפשר הגנה מפני הפעלה חוזרת. |
response_type |
(נדרש) | אם הערך הוא code , מתבצעת הפעלה של תהליך קוד הרשאה בסיסי, שבו נדרש POST לנקודת הקצה של האסימון כדי לקבל את האסימונים. אם הערך הוא token id_token או id_token token , מופעל תהליך סמוי, שבו נדרש שימוש ב-JavaScript בכתובת ה-URI להפניה האוטומטית כדי לאחזר אסימונים ממזהה ה-URI #fragment . |
redirect_uri |
(נדרש) | קובע לאן התשובה נשלחת. הערך של הפרמטר הזה חייב להתאים בדיוק לאחד מערכי ההפניה האוטומטית המורשים שהגדרתם ב- API Console Credentials page (כולל הסכימה HTTP או HTTPS, אותיות רישיות וסימן הספרה '/' בסוף, אם יש). |
scope |
(נדרש) | פרמטר ההיקף חייב להתחיל בערך אם ערך ההיקף אם ערך ההיקף בנוסף להיקפי ההרשאות הספציפיים ל-OpenID, ארגומנט ההיקף יכול לכלול גם ערכים אחרים של היקף. כל ערכי ההיקף חייבים להיות מופרדים באמצעות רווחים. לדוגמה, אם רוצים גישה לפי קובץ ל-Google Drive של משתמש, פרמטר ההיקף יכול להיות למידע על היקפי ההרשאות הזמינים, אפשר לעיין במאמר היקפי ההרשאות של OAuth 2.0 ל-Google APIs או במסמכי העזרה של ממשק ה-API של Google שבו רוצים להשתמש. |
state |
(אופציונלי, אבל מומלץ מאוד) | מחרוזת אטומה שמתבצעת בה חזרה (round-trip) בפרוטוקול. כלומר, היא מוחזרת כפרמטר URI בתהליך הבסיסי, ובמזהה ה-URI השדה |
access_type |
(אופציונלי) | הערכים המותרים הם offline ו-online . ההשפעה מתועדת בקטע גישה אופליין. אם מבקשים אסימון גישה, הלקוח לא מקבל אסימון רענון אלא אם מציינים את הערך offline . |
display |
(אופציונלי) | ערך מחרוזת ASCII שמציין את האופן שבו שרת ההרשאה מציג את דפי ממשק המשתמש של האימות וההסכמה. הערכים הבאים מצוינים ומאושרים על ידי שרתי Google, אבל אין להם השפעה על ההתנהגות שלהם: page , popup , touch ו-wap . |
hd |
(אופציונלי) | ייעול תהליך ההתחברות לחשבונות שבבעלות ארגון ב-Google Cloud. אם תכללו את הדומיין הארגוני של Google Cloud (לדוגמה, mycollege.edu), תוכלו לציין שצריך לבצע אופטימיזציה של ממשק המשתמש לבחירת חשבון עבור חשבונות בדומיין הזה. כדי לבצע אופטימיזציה לחשבונות ארגוניים ב-Google Cloud באופן כללי, במקום רק לדומיין ארגוני אחד ב-Google Cloud, מגדירים ערך של כוכב ( אל תסתמכו על אופטימיזציית ממשק המשתמש הזו כדי לקבוע מי יכול לגשת לאפליקציה, כי אפשר לשנות בקשות בצד הלקוח. חשוב לבדוק שלאסימון המזהה שהוחזר יש ערך של הצהרת |
include_granted_scopes |
(אופציונלי) | אם הפרמטר הזה מסופק עם הערך true , ובקשת ההרשאה מאושרת, ההרשאה תכלול את כל ההרשאות הקודמות שהוקצו לשילוב הזה של משתמש/אפליקציה להיקפים אחרים. מידע נוסף זמין במאמר הרשאה מצטברת.
חשוב לזכור שאי אפשר לבצע הרשאה מצטברת בתהליך של אפליקציה מותקנת. |
login_hint |
(אופציונלי) | כשהאפליקציה יודעת איזה משתמש היא מנסה לאמת, היא יכולה לספק את הפרמטר הזה בתור רמז לשרת האימות. העברת ההצעה הזו מונעת את הצגת בורר החשבונות וממלאת מראש את תיבת האימייל בטופס הכניסה, או בוחרת את הסשן המתאים (אם המשתמש משתמש בכניסה בכמה חשבונות). כך אפשר למנוע בעיות שקורות אם האפליקציה מתחברת לחשבון המשתמש הלא נכון.
הערך יכול להיות כתובת אימייל או המחרוזת sub , שמקבילה למזהה Google של המשתמש. |
prompt |
(אופציונלי) | רשימה של ערכי מחרוזות מופרדים בפסיקים, שמציינת אם שרת ההרשאות יבקש מהמשתמש לבצע אימות מחדש ולהסכים. הערכים האפשריים הם:
אם לא צוין ערך והמשתמש לא העניק גישה בעבר, יוצג לו מסך הסכמה. |
תיקוף של אסימון מזהה
עליכם לאמת את כל אסימוני הזהות בשרת, אלא אם אתם יודעים שהם הגיעו ישירות מ-Google. לדוגמה, השרת צריך לאמת את האותנטיות של כל טוקני הזיהוי שהוא מקבל מאפליקציות הלקוח.
אלה מצבים נפוצים שבהם יכול להיות שתשלחו אסימונים מזהים לשרת:
- שליחת אסימונים מזהים עם בקשות שצריך לאמת. אסימונים מזהים מאפשרים לכם לדעת מהו המשתמש הספציפי ששלח את הבקשה, ולמי הוקצה אסימון המזהה.
אסימוני מזהה הם מידע רגיש, ואפשר לעשות בו שימוש לרעה אם הוא יאוחזר. כדי להבטיח שהאסימונים האלה יטופלו בצורה מאובטחת, צריך להעביר אותם רק דרך HTTPS, ורק באמצעות נתוני POST או בתוך כותרות הבקשה. אם אתם שומרים טוקנים מזהים בשרת, עליכם גם לאחסן אותם באופן מאובטח.
אחד מהיתרונות של אסימונים מזהים הוא העובדה שאפשר להעביר אותם בין רכיבים שונים באפליקציה. הרכיבים האלה יכולים להשתמש באסימון מזהה כמנגנון אימות קל לאימות האפליקציה והמשתמש. עם זאת, כדי שתוכלו להשתמש במידע באסימון המזהה או להסתמך עליו כטענת נכוֹנוּת (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
. אם החתימה על האסימון תקינה, התגובה תהיה המטען הייעודי של ה-JWT בפורמט אובייקט JSON מפוענח.
נקודת הקצה tokeninfo
שימושית לניפוי באגים, אבל למטרות ייצור, צריך לאחזר את המפתחות הציבוריים של Google מנקודת הקצה של המפתחות ולבצע את האימות באופן מקומי. צריך לאחזר את כתובת ה-URI של המפתחות ממסמך הגילוי באמצעות ערך המטא-נתונים jwks_uri
. יכול להיות שהבקשות לנקודת הקצה לניפוי באגים יאוטלו או יהיו נתונות לשגיאות לסירוגין.
Google משנה את המפתחות הציבוריים שלה רק לעיתים רחוקות, כך שאפשר לשמור אותם במטמון באמצעות ההוראות למטמון בתגובה ל-HTTP, וברוב המקרים לבצע אימות מקומי בצורה יעילה הרבה יותר מאשר באמצעות נקודת הקצה tokeninfo
. כדי לבצע את האימות הזה, צריך לאחזר ולנתח אישורים ולבצע את הקריאות הקריפטוגרפיות המתאימות כדי לבדוק את החתימה. למרבה המזל, יש ספריות שעבר תיקון באגים זמינות במגוון רחב של שפות שאפשר להשתמש בהן כדי להשיג את זה (ראו jwt.io).
אחזור פרטים מפרופיל המשתמש
כדי לקבל פרטי פרופיל נוספים על המשתמש, אפשר להשתמש באסימון הגישה (שהאפליקציה מקבלת במהלך תהליך האימות) ובתקן OpenID Connect:
כדי לעמוד בדרישות של OpenID, צריך לכלול את ערכי ההיקף
openid profile
בבקשת האימות.אם רוצים לכלול את כתובת האימייל של המשתמש, אפשר לציין ערך היקף נוסף של
email
. כדי לציין גם אתprofile
וגם אתemail
, אפשר לכלול את הפרמטר הבא ב-URI של בקשת האימות:scope=openid%20profile%20email
- מוסיפים את אסימון הגישה לכותרת ההרשאה ושולחים בקשת
GET
מסוג HTTPS לנקודת הקצה של userinfo. צריך לאחזר את נקודת הקצה הזו ממסמך Discovery באמצעות הערך של המטא-נתוניםuserinfo_endpoint
. התגובה של userinfo כוללת מידע על המשתמש, כפי שמתואר בקטעOpenID Connect Standard Claims
, ואת ערך המטא-נתוניםclaims_supported
של מסמך Discovery. המשתמשים או הארגונים שלהם יכולים לבחור לספק או להסתיר שדות מסוימים, כך שיכול להיות שלא תקבלו מידע לגבי כל השדות בהיקפי הגישה המורשים שלכם.
מסמך Discovery
פרוטוקול OpenID Connect מחייב שימוש במספר נקודות קצה לאימות משתמשים ולבקשת משאבים, כולל אסימונים, פרטי משתמשים ומפתחות ציבוריים.
כדי לפשט את ההטמעות ולהגדיל את הגמישות, ב-OpenID Connect אפשר להשתמש ב'מסמך איתור', מסמך JSON שנמצא במיקום ידוע ומכיל צמדי מפתח/ערך שמספקים פרטים על ההגדרות של ספק OpenID Connect, כולל מזהי ה-URI של נקודות הקצה של ההרשאה, האסימון, הביטול, פרטי המשתמש והמפתחות הציבוריים. אפשר לאחזר את מסמך הגילוי של שירות OpenID Connect של Google מהמקומות הבאים:
https://accounts.google.com/.well-known/openid-configuration
כדי להשתמש בשירותי OpenID Connect של Google, צריך להטמיע את ה-URI של מסמך הגילוי (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" ] }
כדי להימנע מטריק חזרה (round-trip) של HTTP, אפשר לשמור במטמון את הערכים ממסמך הגילוי. נעשה שימוש בכותרות HTTP רגילות לשמירת נתונים במטמון, וצריך לפעול בהתאם להן.
ספריות לקוח
ספריות הלקוח הבאות מאפשרות לשלב את OAuth 2.0 עם מסגרות פופולריות, וכך ליישם אותו בקלות רבה יותר:
תאימות ל-OpenID Connect
מערכת האימות של Google ל-OAuth 2.0 תומכת בתכונות הנדרשות של מפרט OpenID Connect Core. כל לקוח שמיועד לעבודה עם OpenID Connect אמור לפעול בשיתוף פעולה עם השירות הזה (למעט אובייקט הבקשה של OpenID).