Przegląd
16 lutego 2022 r. ogłosiliśmy plany zwiększenia bezpieczeństwa interakcji z Google OAuth przez użycie bezpieczniejszych przepływów OAuth. Z tego przewodnika dowiesz się, jakie zmiany i kroki są konieczne, aby pomyślnie przejść z procesu OAuth poza pasmem (OOB) na obsługiwane alternatywy.
Jest to środek ochrony przed phishingiem i atakami polegającymi na podszywaniu się pod aplikacje podczas interakcji z punktami końcowymi autoryzacji OAuth 2.0 Google.
Co to jest OOB?
Zewnętrzny protokół OAuth (OOB), nazywany też opcją ręcznego kopiowania i wklejania, to starszy proces opracowany z myślą o zainstalowanych klientach, które nie mają identyfikatora URI przekierowania do akceptowania danych uwierzytelniających po zatwierdzeniu przez użytkownika prośby o zgodę na dostęp OAuth. Proces OOB stwarza ryzyko zdalnego phishingu, dlatego klienci muszą przejść na alternatywną metodę, aby chronić się przed tą luką w zabezpieczeniach.
Proces OOB jest wycofywany w przypadku wszystkich typów aplikacji, czyli aplikacji internetowych, aplikacji na Androida, iOS, uniwersalnych aplikacji systemu Windows (UWP), aplikacji Chrome, aplikacji na telewizory i urządzenia z ograniczonymi możliwościami wprowadzania danych oraz aplikacji komputerowych.
Najważniejsze daty dotyczące zgodności
- 28 lutego 2022 r. – nowe użycie protokołu OAuth zostało zablokowane w przypadku przepływu OOB.
- 5 września 2022 r. – w przypadku niezgodnych żądań OAuth może wyświetlać się komunikat ostrzegawczy dla użytkownika.
- 3 października 2022 r. – proces OOB został wycofany w przypadku klientów OAuth utworzonych przed 28 lutego 2022 r.
- 31 stycznia 2023 r. – wszystkie istniejące klienty zostaną zablokowane (w tym klienty wyłączone z blokady).
W przypadku żądań niezgodnych z zasadami wyświetli się komunikat o błędzie dla użytkownika. Wiadomość poinformuje użytkowników, że aplikacja jest zablokowana, i wyświetli adres e-mail do kontaktu z zespołem pomocy, który został zarejestrowany na ekranie zgody OAuth w konsoli Google Cloud.
Proces migracji składa się z 2 głównych etapów:
- Sprawdź, czy problem dotyczy Ciebie.
- Jeśli dotyczy to Twojej aplikacji, przejdź na bezpieczniejszą alternatywę.
Sprawdzanie, czy problem dotyczy Twojej organizacji
Wycofanie dotyczy tylko aplikacji produkcyjnych (czyli aplikacji ze stanem publikacji ustawionym na W produkcji). Proces będzie nadal działać w przypadku aplikacji ze stanem publikacji Testowanie.
Sprawdź stan publikowania w protokole OAuth na stronie Marka w konsoli Google Cloud i przejdź do następnego kroku, jeśli używasz procesu OOB w projekcie ze stanem publikowania „W środowisku produkcyjnym”.
Jak sprawdzić, czy aplikacja korzysta z procesu OOB
Sprawdź kod aplikacji lub wychodzące wywołanie sieciowe (jeśli aplikacja używa biblioteki OAuth), aby ustalić, czy żądanie autoryzacji Google OAuth wysyłane przez aplikację używa wartości identyfikatora URI przekierowania OOB.
Sprawdzanie kodu aplikacji
Sprawdź sekcję kodu aplikacji, w której wywołujesz punkty końcowe autoryzacji Google OAuth, i ustal, czy parametr redirect_uri ma jedną z tych wartości:
redirect_uri=urn:ietf:wg:oauth:2.0:oobredirect_uri=urn:ietf:wg:oauth:2.0:oob:autoredirect_uri=oob
Przykładowe żądanie procesu przekierowania OOB wygląda tak:
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>
Sprawdzanie wychodzącego wywołania sieciowego
Sposób sprawdzania wywołań sieciowych zależy od typu aplikacji.
- Aplikacja internetowa – sprawdzanie aktywności sieciowej w Chrome
- Android – sprawdzanie ruchu w sieci za pomocą Network Inspectora
- Aplikacje Chrome
- Otwórz stronę rozszerzeń do Chrome.
- W prawym górnym rogu strony rozszerzenia zaznacz pole wyboru Tryb programisty.
- Wybierz rozszerzenie, które chcesz monitorować.
- W sekcji Sprawdź widoki na stronie rozszerzenia kliknij link strona w tle.
- Otworzy się okno Narzędzia dla programistów, w którym możesz monitorować ruch w sieci na karcie Sieć.
- iOS – analizowanie ruchu HTTP za pomocą narzędzi
- Aplikacje komputerowe – użyj narzędzia do przechwytywania ruchu sieciowego dostępnego dla systemu operacyjnego, na który została opracowana aplikacja.
Podczas sprawdzania wywołań sieciowych poszukaj żądań wysyłanych do punktów końcowych autoryzacji Google OAuth i sprawdź, czy parametr redirect_uri ma jedną z tych wartości:
redirect_uri=urn:ietf:wg:oauth:2.0:oobredirect_uri=urn:ietf:wg:oauth:2.0:oob:autoredirect_uri=oob
Przykładowe żądanie procesu przekierowania OOB wygląda tak:
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>
Przejście na bezpieczną alternatywę
Klienty mobilne (Android i iOS)
Jeśli ustalisz, że Twoja aplikacja używa procesu OOB z typem aplikacji OAuth na Androida lub iOS, przejdź na zalecane pakiety SDK (Android, iOS).
SDK ułatwia dostęp do interfejsów API Google i obsługuje wszystkie wywołania punktów końcowych autoryzacji OAuth 2.0 Google.
Linki do dokumentacji poniżej zawierają informacje o tym, jak używać zalecanych pakietów SDK do uzyskiwania dostępu do interfejsów API Google bez użycia identyfikatora URI przekierowania OOB.
Dostęp do interfejsów API Google na Androidzie
Dostęp po stronie klienta
Poniższy przykład pokazuje, jak uzyskać dostęp do interfejsów API Google po stronie klienta na Androidzie za pomocą zalecanej biblioteki Google Identity Services na Androida.
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));
Przekaż authorizationResult do zdefiniowanej metody, aby zapisać treść w folderze na dysku użytkownika. Klasa authorizationResult ma metodę getAccessToken(), która zwraca token dostępu.
Dostęp po stronie serwera (offline)
Poniższy przykład pokazuje, jak uzyskać dostęp do interfejsów API Google po stronie serwera na Androidzie.
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 ma metodę getServerAuthCode(), która zwraca kod autoryzacji. Możesz go wysłać do backendu, aby uzyskać token dostępu i token odświeżania.
Uzyskiwanie dostępu do interfejsów API Google w aplikacji na iOS
Dostęp po stronie klienta
Poniższy przykład pokazuje, jak uzyskać dostęp do interfejsów API Google po stronie klienta na 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() }
Użyj tokena dostępu, aby wywołać interfejs API, dołączając token dostępu do nagłówka żądania REST lub gRPC (Authorization: Bearer <var>ACCESS_TOKEN</var>) albo używając modułu pobierającego (GTMFetcherAuthorizationProtocol) z biblioteką klienta interfejsów API Google dla języka Objective-C dla REST.
Zapoznaj się z przewodnikiem po dostępie po stronie klienta, aby dowiedzieć się, jak uzyskać dostęp do interfejsów API Google po stronie klienta.
Dostęp po stronie serwera (offline)
Poniższy przykład pokazuje, jak uzyskać dostęp do interfejsów API Google po stronie serwera, aby obsługiwać klienta 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
}Zapoznaj się z przewodnikiem po dostępie po stronie serwera, aby dowiedzieć się, jak uzyskać dostęp do interfejsów API Google po stronie serwera.
Klient aplikacji Chrome
Jeśli ustalisz, że Twoja aplikacja używa przepływu OOB w kliencie aplikacji Chrome, przejdź na Chrome Identity API.
Poniższy przykład pokazuje, jak pobrać wszystkie kontakty użytkownika bez użycia identyfikatora URI przekierowania OOB.
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) }); }); }); };
Więcej informacji o tym, jak uwierzytelniać użytkowników i wywoływać punkty końcowe Google za pomocą interfejsu Chrome Identity API, znajdziesz w przewodniku po tym interfejsie.
Aplikacja internetowa
Jeśli ustalisz, że Twoja aplikacja używa przepływu OOB w przypadku aplikacji internetowej, przejdź na jedną z naszych bibliotek klienta interfejsów API Google. Zobacz listę bibliotek klienta interfejsów API Google dla różnych języków programowania.
Biblioteki upraszczają dostęp do interfejsów API Google i obsługują wszystkie wywołania punktów końcowych Google.
Dostęp po stronie serwera (offline)
Tryb dostępu po stronie serwera (offline) wymaga wykonania tych czynności :
- Skonfiguruj serwer i zdefiniuj publicznie dostępny punkt końcowy (identyfikator URI przekierowania), aby otrzymywać kod autoryzacji.
- Skonfiguruj identyfikator URI przekierowania na stronie Klienci w konsoli Google Cloud.
Poniższy fragment kodu pokazuje przykład użycia interfejsu Google Drive API w NodeJS do wyświetlania listy plików użytkownika na Dysku Google po stronie serwera bez użycia identyfikatora URI przekierowania 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. }); } } }
Zapoznaj się z przewodnikiem po aplikacjach internetowych po stronie serwera, aby dowiedzieć się, jak uzyskać dostęp do interfejsów API Google po stronie serwera.
Dostęp po stronie klienta
Poniższy fragment kodu w języku JavaScript pokazuje przykład użycia interfejsu API Google do uzyskiwania dostępu do wydarzeń w kalendarzu użytkownika po stronie klienta.
// 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(...); }
Zapoznaj się z przewodnikiem po aplikacji internetowej po stronie klienta, aby dowiedzieć się, jak uzyskać dostęp do interfejsów API Google po stronie klienta.
Klient na komputer
Jeśli ustalisz, że Twoja aplikacja używa procesu OOB na kliencie komputerowym, musisz przejść na proces adresu IP sprzężenia zwrotnego (localhost lub 127.0.0.1).