Włączanie dostępu po stronie serwera do Usług gier Google Play

Po wycofaniu interfejsu Google Sign-In API w 2026 roku usuniemy pakiet SDK do gier w wersji 1. Z końcem lutego 2025 r. nie będzie już można publikować w Google Play nowych tytułów, w których zastosowano integrację z wersją 1 pakietu SDK gier. Zamiast tego zalecamy używanie pakietu SDK do gier w wersji 2.
Dotychczasowe tytuły z integracjami gier w wersji 1 będą działać jeszcze przez kilka lat, ale zachęcamy do przejścia na wersję 2 od czerwca 2025 r.
Ten przewodnik dotyczy korzystania z pakietu SDK usług gier Play w wersji 1. Informacje o najnowszej wersji pakietu SDK znajdziesz w dokumentacji wersji 2.

Jeśli Twoja gra korzysta z serwera backendu, zalecamy używanie logowania przez Google do uwierzytelniania graczy i bezpiecznego przekazywania tożsamości gracza na serwer backendu. Umożliwia to również bezpieczne pobieranie przez grę tożsamości gracza i innych danych bez narażania ich na potencjalne manipulacje podczas przesyłania przez urządzenie.

W takim przypadku gra poprosi gracza o zalogowanie się w Usługach gier Google Play w zwykły sposób. Gdy gracz zaloguje się, obiekt GoogleSignInAccount zawiera specjalny kod jednorazowy (nazywany kodem autoryzacji serwera), który klient przekazuje serwerowi. Następnie na serwerze wymień kod autoryzacji serwera na token OAuth 2.0, którego serwer może używać do wywoływania interfejsu API usług gier Google Play.

Dodatkowe wskazówki dotyczące dodawania logowania w grach znajdziesz w artykule Logowanie w grach na Androida.

Szczegółowy przykładowy kod pokazujący, jak używać logowania przez Google do uwierzytelniania graczy, znajdziesz w clientserverskeletonprzykładzie w GitHubie.

Aby uzyskać dostęp offline, wykonaj te czynności:

  1. W Konsoli Google Play: utwórz dane logowania dla serwera gry. Typ klienta OAuth danych logowania będzie miał wartość „web”.
  2. W aplikacji na Androida: w ramach logowania poproś o kod autoryzacji serwera dla danych logowania serwera i przekaż go na serwer.
  3. Na serwerze gry: wymień kod autoryzacji serwera na token dostępu OAuth za pomocą usług uwierzytelniania Google, a następnie użyj go do wywoływania interfejsów REST API usług gier Play.

Zanim zaczniesz

Zanim zintegrujesz logowanie przez Google z grą, musisz najpierw dodać grę w Konsoli Google Play, zgodnie z opisem w artykule Konfigurowanie usług gier Google Play.

Tworzenie powiązanej aplikacji internetowej po stronie serwera na potrzeby gry

Usługi gier Google Play nie zapewniają obsługi backendu w przypadku gier internetowych. Zapewnia jednak obsługę serwera backendu serwera gry na Androida.

Jeśli chcesz używać interfejsów API REST do usług gier Play w aplikacji po stronie serwera, wykonaj te czynności:

  1. Utwórz powiązaną aplikację internetową do gry w sekcji Połączone aplikacjeKonsoli Google Play. Pamiętaj, że w tym procesie nie używa się launch_url, więc to pole może pozostać puste.
  2. Aby uzyskać informacje o danych logowania aplikacji:
    1. W Konsoli Google Play kliknij Szczegóły gry.
    2. Przewiń w dół do sekcji Projekt w konsoli API i kliknij link do projektu w konsoli API.
    3. Na ekranie Interfejsy API i usługi > Dane logowania w konsoli Google API pobierz plik client_secret.json dla swojej aplikacji internetowej i zapisz go w lokalizacji, do której serwer ma dostęp. Zapisz identyfikator klienta danych logowania, aby móc z niego później skorzystać.
  3. Uruchom ponownie aplikację po stronie serwera, aby była gotowa do przyjmowania żądań z aplikacji klienta gry.

Logowanie na urządzeniu klienta

Klasa GoogleSignInClient jest głównym punktem wejścia do pobierania konta aktualnie zalogowanego gracza i logowania gracza, jeśli nie zrobił tego wcześniej w Twojej aplikacji na urządzeniu.

Aby utworzyć klienta logowania, wykonaj te czynności:

  1. Utwórz klienta logowania za pomocą obiektu GoogleSignInOptions. Aby skonfigurować logowanie w sekcji GoogleSignInOptions.Builder, musisz podać GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN.
  2. Musisz też określić, że gra wymaga kodu autoryzacji dla serwera backendu, wywołując metodę GoogleSignInOptions.Builder.requestServerAuthCode() z identyfikatorem klienta serwera jako parametrem. Kod autoryzacji pobierzesz później na potrzeby tokenów dostępu na serwerze backendu, zgodnie z opisem w sekcji Pobieranie kodu autoryzacji serwera.
  3. Wywołaj metodę GoogleSignIn.getClient() i przekaż skonfigurowane wcześniej opcje. Jeśli wywołanie się powiedzie, interfejs Google Sign-In API zwróci instancję obiektu GoogleSignInClient.
  4. Po uzyskaniu instancji GoogleSignInClient zaloguj gracza w trybie cichym z poziomu onResume() aktywności, zgodnie z opisem w sekcji Przeprowadzanie cichego logowania.

Oto przykład:

private static final int RC_SIGN_IN = 9001;
private GoogleSignInClient mGoogleSignInClient;

private void startSignInForAuthCode() {

  // Client ID for your backend server.
  String webClientId = getString(R.string.webclient_id);

  GoogleSignInOptions signInOption = new
      GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
      .requestServerAuthCode(webClientId)
      .build();

  GoogleSignInClient signInClient = GoogleSignIn.getClient(this, signInOption);
  Intent intent = signInClient.getSignInIntent();
  startActivityForResult(intent, RC_SIGN_IN);
}

Pobieranie kodu autoryzacji serwera

Aby pobrać kod autoryzacji serwera, którego gra może używać do uzyskiwania tokenów dostępu na serwerze backendu, wywołaj metodę getServerAuthCode() obiektu GoogleSignInAccount, który Google Sign-In zwraca po pomyślnym zalogowaniu się gracza.

Oto przykład:

// Auth code to send to backend server.
private String mServerAuthCode;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (requestCode == RC_SIGN_IN) {
    GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
    if (result.isSuccess()) {
      mServerAuthCode = result.getSignInAccount().getServerAuthCode();
    } else {
      String message = result.getStatus().getStatusMessage();
      if (message == null || message.isEmpty()) {
        message = getString(R.string.signin_other_error);
      }
      new AlertDialog.Builder(this).setMessage(message)
          .setNeutralButton(android.R.string.ok, null).show();
    }
  }
}

Wymiana kodu autoryzacji serwera na token dostępu na serwerze

Wyślij kod autoryzacji serwera na serwer backendu, aby wymienić go na tokeny dostępu i odświeżania. Użyj tokena dostępu, aby wywołać interfejs API usług gier Play w imieniu gracza. Opcjonalnie możesz też zapisać token odświeżania, aby uzyskać nowy token dostępu po wygaśnięciu tokena dostępu.

Ten fragment kodu pokazuje, jak możesz wdrożyć kod po stronie serwera w języku programowania Java, aby wymienić kod autoryzacji serwera na tokeny dostępu. Korzysta ona z przykładowej aplikacji clientserverskeleton:

/**
 * Exchanges the authcode for an access token credential.  The credential
 * is the associated with the given player.
 *
 * @param authCode - the non-null authcode passed from the client.
 * @param player   - the player object which the given authcode is
 *                 associated with.
 * @return the HTTP response code indicating the outcome of the exchange.
 */
private int exchangeAuthCode(String authCode, Player player) {
try {

    // The client_secret.json file is downloaded from the Google API
    // console.  This is used to identify your web application.  The
    // contents of this file should not be shared.
    //
    File secretFile = new File("client_secret.json");

    // If we don't have the file, we can't access any APIs, so return
    // an error.
    if (!secretFile.exists()) {
        log("Secret file : " + secretFile
                .getAbsolutePath() + "  does not exist!");
        return HttpServletResponse.SC_FORBIDDEN;
    }

    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(
            JacksonFactory.getDefaultInstance(), new
            FileReader(secretFile));

    // Extract the application id of the game from the client id.
    String applicationId = extractApplicationId(clientSecrets
            .getDetails().getClientId());

    GoogleTokenResponse tokenResponse =
            new GoogleAuthorizationCodeTokenRequest(
            HTTPTransport,
            JacksonFactory.getDefaultInstance(),
            "https://oauth2.googleapis.com/token",
            clientSecrets.getDetails().getClientId(),
            clientSecrets.getDetails().getClientSecret(),
            authCode,
            "")
            .execute();

    log("hasRefresh == " + (tokenResponse.getRefreshToken() != null));
    log("Exchanging authCode: " + authCode + " for token");
    Credential credential = new Credential
            .Builder(BearerToken.authorizationHeaderAccessMethod())
            .setJsonFactory(JacksonFactory.getDefaultInstance())
            .setTransport(HTTPTransport)
            .setTokenServerEncodedUrl("https://www.googleapis.com/oauth2/v4/token")
            .setClientAuthentication(new HttpExecuteInterceptor() {
                @Override
                public void intercept(HttpRequest request)
                        throws IOException {
                        }
            })
            .build()
            .setFromTokenResponse(tokenResponse);

    player.setCredential(credential);

    // Now that we have a credential, we can access the Games API.
    PlayGamesAPI api = new PlayGamesAPI(player, applicationId,
            HTTPTransport, JacksonFactory.getDefaultInstance());

    // Call the verify method, which checks that the access token has
    // access to the Games API, and that the player id used by the
    // client matches the playerId associated with the accessToken.
    boolean ok = api.verifyPlayer();

    // Call a Games API on the server.
    if (ok) {
        ok = api.updatePlayerInfo();
        if (ok) {
            // persist the player.
            savePlayer(api.getPlayer());
        }
    }

    return ok ? HttpServletResponse.SC_OK :
            HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

  } catch (IOException e) {
    e.printStackTrace();
  }
  return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
}

Więcej informacji o uzyskiwaniu dostępu do interfejsów API Google z serwera backendu w imieniu zalogowanego gracza znajdziesz w artykule Włączanie dostępu po stronie serwera.

Obsługa wylogowywania się gracza

Aby wylogować graczy z gry, wywołaj metodę signOut() w obiekcie GoogleSignInClient. Przykładowy fragment kodu znajdziesz w sekcji Wylogowywanie odtwarzacza.

Wywoływanie interfejsów API REST z serwera

Pełny opis dostępnych wywołań interfejsu API znajdziesz w artykule Interfejsy API REST dla usług Google Play Games.

Przykłady wywołań interfejsu API REST, które mogą być przydatne:

Zawodnik

  • Chcesz uzyskać identyfikator zalogowanego gracza i dane profilu? Wywołaj funkcję Players.get, podając 'me' jako identyfikator.

Znajomi

Zapoznaj się z przewodnikiem Znajomi, w którym znajdziesz więcej informacji o tej funkcji.

Osiągnięcia

Zapoznaj się z przewodnikiem Osiągnięcia, w którym znajdziesz szczegółowe wyjaśnienia dotyczące osiągnięć.

  • Chcesz uzyskać listę bieżących osiągnięć? Możesz wywołać metodę AchievementDefinitions.list.
  • Połącz to z wywołaniem funkcji Achievements.list, aby sprawdzić, które osiągnięcia zostały odblokowane przez gracza.
  • Czy gracz zdobył osiągnięcie? Aby je odblokować, użyj funkcji Achievements.unlock.
  • Czy gracz poczynił postępy w zdobywaniu częściowego osiągnięcia? Użyj funkcji Achievements.increment, aby zgłosić postępy (i sprawdzić, czy gracz odblokował osiągnięcie).
  • Czy debugujesz grę, która nie jest jeszcze w wersji produkcyjnej? Spróbuj wywołać Achievements.reset lub Achievements.resetAll z interfejsów Management API, aby zresetować osiągnięcia do pierwotnego stanu.

Tabele wyników

Zapoznaj się z przewodnikiem Tabele wyników, w którym znajdziesz więcej informacji o tabelach wyników.

  • Chcesz uzyskać listę wszystkich tablic wyników w grze? Wywołaj funkcję Leaderboards.list.
  • Czy gracz skończył grę? Możesz przesłać wynik za pomocą funkcji Scores.submit i sprawdzić, czy jest to nowy rekord.
  • Chcesz wyświetlić tabelę wyników? Pobierz dane z Scores.list i wyświetl je użytkownikowi.
  • Użyj metody Scores.listWindow, aby znaleźć różne wyniki zbliżone do najlepszego wyniku użytkownika.
  • Aby uzyskać więcej informacji o wyniku gracza w danej tabeli wyników (np. czy gracz znajduje się w 12% najlepszych graczy), wywołaj metodę Scores.get.
  • Debugujesz grę? Spróbuj wywołać funkcję Scores.reset z interfejsu Management API, aby zresetować wszystkie wyniki danego gracza w konkretnej tabeli wyników.