סקירה כללית
ב-16 בפברואר 2022 הודענו על תוכניות להפוך את האינטראקציות של Google OAuth לבטוחות יותר באמצעות תהליכי OAuth מאובטחים יותר. המדריך הזה יעזור לכם להבין את השינויים והשלבים הנדרשים כדי לעבור בהצלחה מתהליך OAuth מחוץ לתחום (OOB) לחלופות נתמכות.
המאמץ הזה הוא אמצעי הגנה מפני מתקפות פישינג והתחזות לאפליקציות במהלך אינטראקציות עם נקודות הקצה של Google לאימות באמצעות OAuth 2.0.
מה זה OOB?
OAuth מחוץ לתחום (OOB), שנקרא גם "אפשרות ההעתקה וההדבקה הידנית", הוא תהליך מדור קודם שפותח כדי לתמוך בלקוחות מותקנים שאין להם URI להפניה אוטומטית כדי לקבל את פרטי הכניסה אחרי שמשתמש מאשר בקשת הסכמה של OAuth. תהליך ה-OOB חושף את הלקוחות לסיכון של פישינג מרחוק, ולכן הם צריכים לעבור לשיטה חלופית כדי להגן על עצמם מפני נקודת החולשה הזו.
תהליך ה-OOB יוצא משימוש בכל סוגי האפליקציות – כלומר, אפליקציות אינטרנט, Android, iOS, Universal Windows Platform (UWP), אפליקציות Chrome, טלוויזיות ומכשירים עם קלט מוגבל, אפליקציות למחשב.
תאריכים חשובים לעמידה בדרישות
- 28 בפברואר 2022 – חסימת שימוש חדש ב-OAuth בתהליך OOB
- 5 בספטמבר 2022 – יכול להיות שתוצג למשתמשים הודעת אזהרה בבקשות OAuth שלא עומדות בדרישות
- 3 באוקטובר 2022 – תהליך ה-OOB הוצא משימוש בלקוחות OAuth שנוצרו לפני 28 בפברואר 2022.
- 31 בינואר 2023 – כל הלקוחות הקיימים נחסמים (כולל לקוחות פטורים)
בבקשות שלא עומדות בדרישות תוצג הודעת שגיאה למשתמשים. ההודעה תבהיר למשתמשים שהאפליקציה חסומה, ותציג את כתובת האימייל לתמיכה שרשמתם במסך ההסכמה של OAuth במסוף Google Cloud.
תהליך ההעברה מורכב משני שלבים עיקריים:
- איך בודקים אם הבעיה משפיעה על האתר שלכם.
- אם אתם מושפעים מהשינוי, עברו לחלופה מאובטחת יותר.
איך בודקים אם הבעיה משפיעה עליכם
ההוצאה משימוש רלוונטית רק לאפליקציות בסביבת הייצור (כלומר, אפליקציות שסטטוס הפרסום שלהן מוגדר כבסביבת הייצור. התהליך ימשיך לפעול באפליקציות עם סטטוס פרסום לבדיקה.
בודקים את סטטוס הפרסום בדף המיתוג של OAuth במסוף Google Cloud. אם אתם משתמשים בתהליך OOB בפרויקט עם סטטוס הפרסום "בייצור", ממשיכים לשלב הבא.
איך בודקים אם האפליקציה משתמשת בתהליך OOB
בודקים את קוד האפליקציה או את הקריאה היוצאת לרשת (אם האפליקציה משתמשת בספריית OAuth) כדי לקבוע אם בקשת ההרשאה של Google OAuth שהאפליקציה שולחת משתמשת בערך של URI להפניה אוטומטית מסוג OOB.
בדיקת קוד האפליקציה
בודקים את הקטע בקוד האפליקציה שבו מתבצעות קריאות לנקודות הקצה לאימות של Google OAuth, וקובעים אם הפרמטר redirect_uri מכיל אחד מהערכים הבאים:
redirect_uri=urn:ietf:wg:oauth:2.0:oobredirect_uri=urn:ietf:wg:oauth:2.0:oob:autoredirect_uri=oob
דוגמה לבקשה של תהליך הפניה אוטומטית מסוג OOB:
https://accounts.google.com/o/oauth2/v2/auth? response_type=code& scope=<SCOPES>& state=<STATE>& redirect_uri=urn:ietf:wg:oauth:2.0:oob& client_id=<CLIENT_ID>
בדיקת קריאה יוצאת לרשת
השיטה לבדיקת קריאות לרשת משתנה בהתאם לסוג האפליקציה.
- אפליקציית אינטרנט – בדיקת הפעילות ברשת ב-Chrome
- Android – בדיקת התנועה ברשת באמצעות Network Inspector
- אפליקציות Chrome
- עוברים אל דף התוספים ל-Chrome.
- מסמנים את התיבה מצב פיתוח בפינה השמאלית העליונה של דף התוספים.
- בוחרים את התוסף שרוצים לעקוב אחריו.
- לוחצים על הקישור דף רקע בקטע בדיקת תצוגות בדף התוסף.
- תיבת הדו-שיח כלים למפתחים תיפתח, ותוכלו לעקוב אחרי התנועה ברשת בכרטיסייה "רשת".
- iOS – ניתוח תנועת HTTP באמצעות Instruments
- אפליקציות למחשב – משתמשים בכלי לתיעוד תעבורת נתונים ברשת שזמין למערכת ההפעלה שעבורה פותחה האפליקציה.
בזמן בדיקת הקריאות ברשת, חפשו בקשות שנשלחות לנקודות הקצה לאימות של Google OAuth, ובדקו אם הפרמטר redirect_uri מכיל אחד מהערכים הבאים:
redirect_uri=urn:ietf:wg:oauth:2.0:oobredirect_uri=urn:ietf:wg:oauth:2.0:oob:autoredirect_uri=oob
דוגמה לבקשה של תהליך הפניה אוטומטית מסוג OOB:
https://accounts.google.com/o/oauth2/v2/auth? response_type=code& scope=<SCOPES>& state=<STATE>& redirect_uri=urn:ietf:wg:oauth:2.0:oob& client_id=<CLIENT_ID>
מעבר לחלופה מאובטחת
אפליקציות לקוח לנייד (Android ו-iOS)
אם אתם מזהים שהאפליקציה שלכם משתמשת בתהליך OOB עם סוג אפליקציית OAuth ל-Android או ל-iOS, אתם צריכים לעבור לשימוש בערכות ה-SDK המומלצות (Android, iOS).
ה-SDK עוזר לכם לגשת ל-Google APIs ומטפל בכל הקריאות לנקודות הקצה של ההרשאה באמצעות OAuth 2.0 של Google.
בקישורים הבאים למסמכי התיעוד מוסבר איך להשתמש בערכות ה-SDK המומלצות כדי לגשת לממשקי Google API בלי להשתמש ב-URI להפניה אוטומטית מחוץ לאפליקציה.
גישה ל-Google APIs ב-Android
גישה מצד הלקוח
בדוגמה הבאה מוסבר איך לגשת לממשקי Google API בצד הלקוח ב-Android באמצעות ספריית Android המומלצת של Google Identity Services.
List<Scopes> requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA);
AuthorizationRequest authorizationRequest =
AuthorizationRequest.builder()
.setRequestedScopes(requestedScopes)
.build();
Identity.getAuthorizationClient(activity)
.authorize(authorizationRequest)
.addOnSuccessListener(
authorizationResult -> {
if (authorizationResult.hasResolution()) {
// Access needs to be granted by the user
PendingIntent pendingIntent =
authorizationResult.getPendingIntent();
try {
startIntentSenderForResult(
pendingIntent.getIntentSender(),
REQUEST_AUTHORIZE, null, 0, 0, 0, null);
} catch (IntentSender.SendIntentException e) {
Log.e(
TAG,
"Couldn't start Authorization UI: "
+ e.getLocalizedMessage());
}
} else {
// Access already granted, continue with user action
saveToDriveAppFolder(authorizationResult);
}
})
.addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
מעבירים את authorizationResult לשיטה שהגדרתם כדי לשמור תוכן בתיקיית Drive של המשתמש. ב-authorizationResult יש את ה-method getAccessToken() שמחזירה את טוקן הגישה.
גישה בצד השרת (אופליין)
בדוגמה הבאה מוסבר איך לגשת לממשקי Google API בצד השרת ב-Android.
List<Scopes> requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA); AuthorizationRequest authorizationRequest = AuthorizationRequest.builder() .requestOfflineAccess(webClientId) .setRequestedScopes(requestedScopes) .build(); Identity.getAuthorizationClient(activity) .authorize(authorizationRequest) .addOnSuccessListener( authorizationResult -> { if (authorizationResult.hasResolution()) { // Access needs to be granted by the user PendingIntent pendingIntent = authorizationResult.getPendingIntent(); try { startIntentSenderForResult( pendingIntent.getIntentSender(), REQUEST_AUTHORIZE, null, 0, 0, 0, null); } catch (IntentSender.SendIntentException e) { Log.e( TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage()); } } else { String authCode = authorizationResult.getServerAuthCode(); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
ל-authorizationResult יש את ה-method getServerAuthCode() שמחזירה את קוד ההרשאה שאפשר לשלוח לקצה העורפי כדי לקבל אסימון גישה ואסימון רענון.
גישה ל-Google APIs באפליקציה ל-iOS
גישה מצד הלקוח
בדוגמה הבאה מוסבר איך לגשת ל-Google APIs בצד הלקוח ב-iOS.
user.authentication.do { authentication, error in guard error == nil else { return } guard let authentication = authentication else { return } // Get the access token to attach it to a REST or gRPC request. let accessToken = authentication.accessToken // Or, get an object that conforms to GTMFetcherAuthorizationProtocol for // use with GTMAppAuth and the Google APIs client library. let authorizer = authentication.fetcherAuthorizer() }
משתמשים באסימון הגישה כדי לשלוח קריאה ל-API, על ידי הכללת אסימון הגישה בכותרת של בקשת REST או gRPC (Authorization: Bearer <var>ACCESS_TOKEN</var>), או על ידי שימוש במאשר של ה-fetcher (GTMFetcherAuthorizationProtocol) עם ספריית הלקוח של Google APIs ל-Objective-C ל-REST.
במדריך לגישה בצד הלקוח מוסבר איך לגשת ל-Google APIs בצד הלקוח.
גישה בצד השרת (אופליין)
בדוגמה הבאה מוסבר איך לגשת לממשקי Google API בצד השרת כדי לתמוך בלקוח iOS.
GIDSignIn.sharedInstance.signIn(
with: signInConfig, presenting: self
) { user, error in
guard error == nil else { return }
guard let user = user else { return }
// request a one-time authorization code that your server exchanges for
// an access token and refresh token
let authCode = user.serverAuthCode
}במדריך לגישה בצד השרת מוסבר איך לגשת לממשקי Google API מצד השרת.
לקוח: אפליקציית Chrome
אם אתם מזהים שהאפליקציה שלכם משתמשת בתהליך OOB בלקוח של אפליקציית Chrome, אתם צריכים לעבור לשימוש ב-Chrome Identity API.
בדוגמה הבאה מוסבר איך לקבל את כל אנשי הקשר של המשתמש בלי להשתמש ב-URI להפניה אוטומטית מחוץ לאפליקציה.
window.onload = function() { document.querySelector('button').addEventListener('click', function() { // retrieve access token chrome.identity.getAuthToken({interactive: true}, function(token) { // .......... // the following example shows how to use a retrieved access token with an // appropriate scope to call the Google People API contactGroups.get endpoint fetch( 'https://people.googleapis.com/v1/contactGroups/all' + '?maxMembers=20&key=API_KEY', init) .then((response) => response.json()) .then(function(data) { console.log(data) }); }); }); };
במדריך של Chrome Identity API מוסבר איך לאמת משתמשים ולקרוא לנקודות קצה (endpoint) של Google באמצעות Chrome Identity API.
אפליקציית אינטרנט
אם אתם מזהים שהאפליקציה שלכם משתמשת בתהליך OOB לאפליקציית אינטרנט, אתם צריכים לעבור להשתמש באחת מספריות הלקוח של Google API. רשימה של ספריות לקוח של Google API לשפות תכנות שונות.
הספריות מפשטות את הגישה לממשקי Google API ומטפלות בכל הקריאות לנקודות הקצה של Google.
גישה בצד השרת (אופליין)
כדי להשתמש במצב גישה בצד השרת (אופליין), צריך לבצע את הפעולות הבאות :
- מגדירים שרת ונקודת קצה שנגישה לציבור (כתובת ה-URI להפניה אוטומטית) כדי לקבל את קוד ההרשאה.
- מגדירים את כתובת ה-URI להפניה אוטומטית בדף Clients במסוף Google Cloud.
בקטע הקוד הבא אפשר לראות דוגמה ל-NodeJS לשימוש ב-Google Drive API כדי להציג רשימה של קובצי Google Drive של משתמש בצד השרת בלי להשתמש ב-URI להפניה אוטומטית של OOB.
async function main() { const server = http.createServer(async function (req, res) { if (req.url.startsWith('/oauth2callback')) { let q = url.parse(req.url, true).query; if (q.error) { console.log('Error:' + q.error); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { // TODO(developer): Handle response / error. }); } } }
במדריך לאפליקציות אינטרנט בצד השרת מוסבר איך לגשת לממשקי Google API מצד השרת.
גישה מצד הלקוח
קטע הקוד הבא, ב-JavaScript, מראה דוגמה לשימוש ב-Google API כדי לגשת לאירועים ביומן של המשתמש בצד הלקוח.
// initTokenClient() initializes a new token client with your // web app's client ID and the scope you need access to const client = google.accounts.oauth2.initTokenClient({ client_id: 'YOUR_GOOGLE_CLIENT_ID', scope: 'https://www.googleapis.com/auth/calendar.readonly', // callback function to handle the token response callback: (tokenResponse) => { if (tokenResponse && tokenResponse.access_token) { gapi.client.setApiKey('YOUR_API_KEY'); gapi.client.load('calendar', 'v3', listUpcomingEvents); } }, }); function listUpcomingEvents() { gapi.client.calendar.events.list(...); }
במדריך לאפליקציות אינטרנט בצד הלקוח מוסבר איך לגשת לממשקי Google API מצד הלקוח.
תוכנת לקוח למחשב
אם אתם מזהים שהאפליקציה שלכם משתמשת בתהליך OOB בלקוח למחשב, אתם צריכים לעבור לשימוש בתהליך של כתובת IP מסוג הלולאה החוזרת (loop) (localhost או 127.0.0.1).