Uwierzytelnij się na serwerze zaplecza

Jeśli korzystasz z logowania przez Google z aplikacją lub witryną, która komunikuje się z serwerem zaplecza, może być konieczne zidentyfikowanie aktualnie zalogowanego użytkownika na serwerze. Aby to zrobić w bezpieczny sposób, po pomyślnym zalogowaniu się użytkownika wyślij token identyfikatora użytkownika na swój serwer przy użyciu protokołu HTTPS. Następnie na serwerze zweryfikuj integralność tokena ID i użyj informacji o użytkowniku zawartych w tokenie, aby nawiązać sesję lub utworzyć nowe konto.

Wyślij token ID na swój serwer

Po pomyślnym zalogowaniu się użytkownika pobierz token identyfikatora użytkownika:

- (void)signIn:(GIDSignIn *)signIn
    didSignInForUser:(GIDGoogleUser *)user
           withError:(NSError *)error {
  NSString *idToken = user.authentication.idToken;
  ...
}

Następnie wyślij token ID na swój serwer z żądaniem HTTPS POST:

NSString *signinEndpoint = @"https://yourbackend.example.com/tokensignin";
NSDictionary *params = @{@"idtoken": idToken};

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:signinEndpoint];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[self httpBodyForParamsDictionary:params]];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request
                                   queue:queue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                         if (error) {
                           NSLog(@"Error: %@", error.localizedDescription);
                         } else {
                           NSLog(@"Signed in as %@", data.bytes);
                         }
                       }];

Sprawdź integralność tokena identyfikatora

Po otrzymaniu tokenu identyfikatora przez HTTPS POST, należy zweryfikować integralność tokenu. Aby sprawdzić, czy token jest prawidłowy, upewnij się, że są spełnione następujące kryteria:

  • Token ID jest poprawnie podpisany przez Google. Użyj kluczy publicznych Google (dostępnych w formacie JWK lub PEM ), aby zweryfikować podpis tokena. Te klucze są regularnie zmieniane; sprawdź nagłówek Cache-Control w odpowiedzi, aby określić, kiedy należy je ponownie pobrać.
  • Wartość aud w tokenie identyfikatora jest równa jednemu z identyfikatorów klienta aplikacji. To sprawdzenie jest konieczne, aby zapobiec używaniu tokenów identyfikacyjnych wystawionych do złośliwej aplikacji w celu uzyskania dostępu do danych o tym samym użytkowniku na serwerze zaplecza aplikacji.
  • Wartość iss w tokena id jest równe accounts.google.com lub https://accounts.google.com .
  • Nie upłynął czas wygaśnięcia ( exp ) tokena identyfikatora.
  • Jeśli chcesz ograniczyć dostęp tylko do członków domeny G Suite, sprawdź, czy token identyfikatora zawiera roszczenie hd zgodne z nazwą domeny G Suite.

Zamiast pisać własny kod w celu wykonania tych czynności weryfikacyjnych, zdecydowanie zalecamy korzystanie z biblioteki klienta interfejsu API Google dla swojej platformy lub biblioteki JWT ogólnego przeznaczenia. W przypadku programowania i debugowania możesz wywołać nasz punkt końcowy walidacji tokeninfo .

Korzystanie z biblioteki klienta interfejsu API Google

Korzystanie z jednej z bibliotek klienta Google API (np. Java , Node.js , PHP , Python ) jest zalecanym sposobem walidacji tokenów Google ID w środowisku produkcyjnym.

Jawa

Aby zweryfikować token identyfikatora w Javie, użyj obiektu GoogleIdTokenVerifier . Na przykład:

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

...

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
    // Specify the CLIENT_ID of the app that accesses the backend:
    .setAudience(Collections.singletonList(CLIENT_ID))
    // Or, if multiple clients access the backend:
    //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
    .build();

// (Receive idTokenString by HTTPS POST)

GoogleIdToken idToken = verifier.verify(idTokenString);
if (idToken != null) {
  Payload payload = idToken.getPayload();

  // Print user identifier
  String userId = payload.getSubject();
  System.out.println("User ID: " + userId);

  // Get profile information from payload
  String email = payload.getEmail();
  boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
  String name = (String) payload.get("name");
  String pictureUrl = (String) payload.get("picture");
  String locale = (String) payload.get("locale");
  String familyName = (String) payload.get("family_name");
  String givenName = (String) payload.get("given_name");

  // Use or store profile information
  // ...

} else {
  System.out.println("Invalid ID token.");
}

Metoda GoogleIdTokenVerifier.verify() weryfikuje podpis JWT, żądanie aud żądanie iss i żądanie exp .

Jeśli chcesz ograniczyć dostęp tylko do członków swojej domeny G Suite, zweryfikuj również roszczenie hd , sprawdzając nazwę domeny zwróconą przez Payload.getHostedDomain() .

Node.js

Aby zweryfikować token identyfikatora w Node.js, użyj biblioteki Google Auth Library dla Node.js. Zainstaluj bibliotekę:

npm install google-auth-library --save
Następnie wywołaj funkcję verifyIdToken() . Na przykład:

const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client(CLIENT_ID);
async function verify() {
  const ticket = await client.verifyIdToken({
      idToken: token,
      audience: CLIENT_ID,  // Specify the CLIENT_ID of the app that accesses the backend
      // Or, if multiple clients access the backend:
      //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
  });
  const payload = ticket.getPayload();
  const userid = payload['sub'];
  // If request specified a G Suite domain:
  // const domain = payload['hd'];
}
verify().catch(console.error);

Funkcja verifyIdToken weryfikuje podpis JWT, żądanie aud żądanie exp i żądanie iss .

Jeśli chcesz ograniczyć dostęp tylko do członków swojej domeny G Suite, sprawdź też, czy roszczenie hd zgodne z nazwą domeny G Suite.

PHP

Aby zweryfikować token identyfikatora w PHP, użyj biblioteki klienta interfejsu API Google dla PHP . Zainstaluj bibliotekę (na przykład używając Composera):

composer require google/apiclient
Następnie wywołaj funkcję verifyIdToken() . Na przykład:

require_once 'vendor/autoload.php';

// Get $id_token via HTTPS POST.

$client = new Google_Client(['client_id' => $CLIENT_ID]);  // Specify the CLIENT_ID of the app that accesses the backend
$payload = $client->verifyIdToken($id_token);
if ($payload) {
  $userid = $payload['sub'];
  // If request specified a G Suite domain:
  //$domain = $payload['hd'];
} else {
  // Invalid ID token
}

Funkcja verifyIdToken weryfikuje podpis JWT, żądanie aud żądanie exp i żądanie iss .

Jeśli chcesz ograniczyć dostęp tylko do członków swojej domeny G Suite, sprawdź też, czy roszczenie hd zgodne z nazwą domeny G Suite.

Pyton

Aby zweryfikować token identyfikatora w Pythonie, użyj funkcji verify_oauth2_token . Na przykład:

from google.oauth2 import id_token
from google.auth.transport import requests

# (Receive token by HTTPS POST)
# ...

try:
    # Specify the CLIENT_ID of the app that accesses the backend:
    idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)

    # Or, if multiple clients access the backend server:
    # idinfo = id_token.verify_oauth2_token(token, requests.Request())
    # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]:
    #     raise ValueError('Could not verify audience.')

    # If auth request is from a G Suite domain:
    # if idinfo['hd'] != GSUITE_DOMAIN_NAME:
    #     raise ValueError('Wrong hosted domain.')

    # ID token is valid. Get the user's Google Account ID from the decoded token.
    userid = idinfo['sub']
except ValueError:
    # Invalid token
    pass

Funkcja verify_oauth2_token weryfikuje podpis verify_oauth2_token JWT, roszczenie aud i żądanie exp . Musisz również zweryfikować roszczenie hd (jeśli dotyczy), badając obiekt, który zwraca verify_oauth2_token . Jeśli wielu klientów uzyskuje dostęp do serwera zaplecza, należy również ręcznie zweryfikować oświadczenie o aud .

Wywołanie punktu końcowego Tokeninfo

tokeninfo sposobem sprawdzenia poprawności podpisu tokena identyfikatora do debugowania jest użycie punktu końcowego tokeninfo . Wywołanie tego punktu końcowego wiąże się z dodatkowym żądaniem sieciowym, które wykonuje większość weryfikacji za Ciebie, podczas gdy Ty testujesz poprawność i wyodrębnianie ładunku we własnym kodzie. Nie nadaje się do użycia w kodzie produkcyjnym, ponieważ żądania mogą być ograniczane lub w inny sposób podlegać sporadycznym błędom.

Aby zweryfikować token identyfikatora za pomocą punktu końcowego tokeninfo , wykonaj żądanie HTTPS POST lub GET do punktu końcowego i przekaż token identyfikatora w parametrze id_token . Na przykład, aby zweryfikować token „XYZ123”, wykonaj następujące żądanie GET:

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

Jeśli token jest poprawnie podpisany, a oświadczenia iss i exp mają oczekiwane wartości, otrzymasz odpowiedź HTTP 200, w której treść zawiera oświadczenia tokenu identyfikatora w formacie JSON. Oto przykładowa odpowiedź:

{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

Jeśli jesteś klientem G Suite, może Cię również zainteresować roszczenie hd , które wskazuje hostowaną domenę użytkownika. Można to wykorzystać do ograniczenia dostępu do zasobu tylko do członków określonych domen. Brak tego twierdzenia oznacza, że ​​użytkownik nie należy do domeny hostowanej w G Suite.

Utwórz konto lub sesję

Po zweryfikowaniu tokena sprawdź, czy użytkownik znajduje się już w Twojej bazie danych użytkowników. Jeśli tak, ustanów uwierzytelnioną sesję dla użytkownika. Jeśli użytkownika nie ma jeszcze w bazie danych użytkowników, utwórz nowy rekord użytkownika na podstawie informacji zawartych w ładunku tokenu identyfikatora i ustanów sesję dla użytkownika. Możesz poprosić użytkownika o dodatkowe informacje o profilu, których potrzebujesz, gdy wykryjesz nowo utworzonego użytkownika w swojej aplikacji.

Zabezpieczanie kont użytkowników za pomocą funkcji Cross Account Protection

Gdy polegasz na Google przy logowaniu użytkownika, automatycznie korzystasz ze wszystkich funkcji bezpieczeństwa i infrastruktury stworzonej przez Google w celu ochrony danych użytkownika. Jednak w mało prawdopodobnym przypadku włamania na konto Google użytkownika lub w przypadku innego istotnego zdarzenia związanego z bezpieczeństwem Twoja aplikacja może być również narażona na atak. Aby lepiej chronić swoje konta przed poważnymi zdarzeniami związanymi z bezpieczeństwem, skorzystaj z funkcji ochrony między kontami, aby otrzymywać alerty bezpieczeństwa od Google. Otrzymując te zdarzenia, uzyskujesz wgląd w ważne zmiany dotyczące bezpieczeństwa konta Google użytkownika, a następnie możesz podjąć działania w swojej usłudze, aby zabezpieczyć swoje konta.