Przewodnik migracji przepływu adresu IP sprzężenia zwrotnego

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 przepływu adresu IP sprzężenia zwrotnego 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.

Jak działa przepływ adresu IP sprzężenia zwrotnego?

Przepływ adresu IP pętli zwrotnej obsługuje użycie adresu IP pętli zwrotnej lub localhost jako komponentu hosta identyfikatora URI przekierowania, do którego są wysyłane dane logowania po zatwierdzeniu przez użytkownika prośby o zgodę na OAuth. Ten przepływ jest podatny na ataki typu man in the middle, w których złośliwa aplikacja, uzyskując dostęp do tego samego interfejsu pętli zwrotnej w niektórych systemach operacyjnych, może przechwycić odpowiedź z serwera autoryzacji do danego identyfikatora URI przekierowania i uzyskać dostęp do kodu autoryzacji.

Przepływ adresu IP sprzężenia zwrotnego jest wycofywany w przypadku aplikacji OAuth na iOS, Androida i Chrome, ale nadal będzie obsługiwany w aplikacjach komputerowych.

Najważniejsze daty dotyczące zgodności

  • 14 marca 2022 r. – nowi klienci OAuth nie będą mogli korzystać z przepływu adresu IP pętli zwrotnej.
  • 1 sierpnia 2022 r. – w przypadku żądań OAuth niezgodnych z zasadami może być wyświetlany komunikat ostrzegawczy dla użytkownika.
  • 31 sierpnia 2022 r. – przepływ adresu IP pętli zwrotnej zostanie zablokowany w przypadku klientów OAuth na Androida, iOS i w aplikacji Chrome utworzonych przed 14 marca 2022 r.
  • 21 października 2022 r. – wszyscy dotychczasowi klienci zostaną zablokowani (w tym klienci wyłączeni 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.

Aby przeprowadzić proces migracji, musisz wykonać 2 główne czynności:

  1. Sprawdź, czy problem dotyczy Ciebie.
  2. Jeśli dotyczy to Twojego konta, przejdź na obsługiwaną metodę alternatywną.

Sprawdzanie, czy problem dotyczy Twojej organizacji

Sprawdzanie typu aplikacji OAuth

Otwórz stronę Klienci w konsoli Google Cloud i wyświetl typ aplikacji OAuth w sekcji Identyfikatory klienta OAuth 2.0. Będzie to jedna z tych opcji: Aplikacja internetowa, Android, iOS, Uniwersalna platforma systemu Windows (UWP), Aplikacja Chrome, Telewizory i urządzenia wejściowe z ograniczonymi możliwościami, Aplikacja komputerowa.

Jeśli Twoja aplikacja jest przeznaczona na Androida, Aplikacje Chrome lub iOS i używasz przepływu adresu IP sprzężenia zwrotnego, przejdź do następnego kroku.

Jeśli używasz procesu adresu IP pętli zwrotnej w kliencie OAuth aplikacji komputerowej, nie musisz nic robić w związku z tym wycofaniem, ponieważ użycie tego typu aplikacji OAuth będzie nadal obsługiwane.

Jak sprawdzić, czy aplikacja używa przepływu adresu IP sprzężenia zwrotnego

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 sprzężenia zwrotnego.

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=http://127.0.0.1:<port> (na przykład redirect_uri=http://127.0.0.1:3000)
  • redirect_uri=http://[::1]:<port> (na przykład redirect_uri=http://[::1]:3000)
  • redirect_uri=http://localhost:<port> (na przykład redirect_uri=http://localhost:3000)

Przykładowe żądanie przekierowania na adres IP sprzężenia zwrotnego wygląda tak:

https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

Sprawdzanie wychodzącego wywołania sieciowego

Sposób sprawdzania wywołań sieciowych zależy od typu aplikacji.

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=http://127.0.0.1:<port> (na przykład redirect_uri=http://127.0.0.1:3000)
  • redirect_uri=http://[::1]:<port> (na przykład redirect_uri=http://[::1]:3000)
  • redirect_uri=http://localhost:<port> (na przykład redirect_uri=http://localhost:3000)

Przykładowe żądanie przekierowania na adres IP sprzężenia zwrotnego wygląda tak:

https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

Przejście na obsługiwaną alternatywę

Klienty mobilne (Android i iOS)

Jeśli ustalisz, że Twoja aplikacja używa przepływu adresu IP sprzężenia zwrotnego 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żywania identyfikatora URI przekierowania adresu IP sprzężenia zwrotnego.

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 adresu IP sprzężenia zwrotnego 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 adresu IP sprzężenia zwrotnego.

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.