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

Jeśli gra korzysta z serwera backendu, zalecamy korzystanie z logowania przez Google do uwierzytelniania graczy i bezpiecznego przekazywania ich tożsamości do serwera backendu. Dzięki temu gra może też bezpiecznie pobierać tożsamość gracza i inne dane bez narażania go na potencjalne modyfikacje podczas przesyłania przez urządzenie.

W takim przypadku gra prosi gracza o logowanie się w Usługach Gier Google Play w zwykły sposób. Gdy gracz zaloguje się pomyślnie, obiekt GoogleSignInAccount zawiera specjalny kod jednorazowego użytku (nazywany kodem autoryzacji serwera), który klient przekazuje serwerowi. Następnie na serwerze zastąp kod autoryzacji serwera tokenem OAuth 2.0, którego serwer może używać do wywoływania interfejsu API usług gier Google Play.

Więcej wskazówek na temat dodawania logowania w grach znajdziesz w artykule Logowanie w grach na Androida.

Szczegółowy przykład kodu pokazujący, jak używać funkcji Logowania w Google do uwierzytelniania graczy, znajdziesz w clientserverskeleton na GitHubie.

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

  1. W Konsoli Google Play: utwórz dane logowania do serwera gier. Typ klienta OAuth danych uwierzytelniających to „web” (sieć).
  2. W aplikacji na Androida: w ramach logowania poproś o kod uwierzytelniający serwer dla danych logowania serwera i przekaż go na serwer.
  3. Na serwerze gry: za pomocą usług uwierzytelniania Google zastąp kod autoryzacji serwera tokenem dostępu OAuth, a potem używaj go do wywoływania interfejsów REST API usług gier Play.

Zanim zaczniesz

Zanim zintegrujesz logowanie w Google ze swoją 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 dla gry

Usługi Google Play dotyczące gier nie zapewniają obsługi backendu gier w przeglądarce. Zapewnia jednak obsługę serwera backendu dla serwera gry na Androida.

Jeśli w swojej aplikacji po stronie serwera chcesz używać interfejsów API typu REST dla usług Gier Google Play, wykonaj te czynności:

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

Logowanie się na kliencie

Klasa GoogleSignInClient to główny punkt wejścia do pobierania danych z konta aktualnie zalogowanego gracza oraz logowania go, jeśli nie zrobił tego wcześniej w aplikacji na urządzeniu.

Aby utworzyć klienta logowania:

  1. Utwórz klienta logowania za pomocą obiektu GoogleSignInOptions. Aby skonfigurować logowanie, musisz w sekcji GoogleSignInOptions.Builder podać wartość GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN.
  2. Musisz też określić, że gra wymaga kodu uwierzytelniania dla serwera backendu. Aby to zrobić, wywołaj metodę GoogleSignInOptions.Builder.requestServerAuthCode(), podając jako parametr identyfikator klienta serwera. Kod autoryzacji będzie potrzebny później do tokenów dostępu na serwerze zaplecza. Aby go pobrać, wykonaj czynności opisane w sekcji Pobieranie kodu autoryzacji serwera.
  3. Wywołaj metodę GoogleSignIn.getClient() i przekaż skonfigurowane wcześniej opcje. Jeśli wywołanie zakończy się powodzeniem, interfejs Google Sign-In API zwróci wystąpienie obiektu GoogleSignInClient.
  4. Po uzyskaniu wystąpienia GoogleSignInClient należy zalogować gracza onResume() w trybie cichym z poziomu aktywności, zgodnie z opisem w artykule Logowanie cichym.

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 tokenów dostępu na serwerze backendu, wywołaj metodę getServerAuthCode() obiektu GoogleSignInAccount, który zwraca logowanie Google 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 uwierzytelniania serwera na token dostępu na serwerze

Wyślij kod uwierzytelniania serwera do serwera zaplecza, aby wymienić go na tokeny dostępu i odświeżania. Użyj tokena dostępu do wywołania interfejsu API Usług gier Google Play w imieniu gracza. Opcjonalnie możesz zapisać token odświeżania, aby po wygaśnięciu tokena dostępu uzyskać nowy.

Ten fragment kodu pokazuje, jak zastosować kod po stronie serwera w języku programowania Java, aby zamienić kod uwierzytelniania serwera na tokeny dostępu. Jest ona oparta na 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 odtwarzacza znajdziesz w sekcji Włączanie dostępu po stronie serwera.

Obsługa wylogowania 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 typu REST z serwera

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

Przykłady wywołań interfejsu API REST, które mogą Ci się przydać:

Zawodnik

  • Chcesz pobrać identyfikator i dane profilu zalogowanego gracza? Wywołaj funkcję Players.get z identyfikatorem 'me'.

Znajomi

Zapoznaj się z przewodnikiem na temat znajomych, który zawiera więcej informacji na ten temat.

Osiągnięcia

Zapoznaj się z przewodnikiem dotyczącym osiągnięć, który zawiera więcej informacji o tym temacie.

  • Chcesz zobaczyć listę aktualnych osiągnięć? Możesz wywołać AchievementDefinitions.list.
  • Połącz to z wywołaniem Achievements.list, aby dowiedzieć się, które z nich gracz odblokował.
  • Czy gracz zdobył osiągnięcie? Aby go odblokować, użyj platformy Osiągnięcia.unlock.
  • Czy gracz poczynił postępy w kierunku 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? Aby zresetować osiągnięcia do pierwotnego stanu, spróbuj wywołać Achievements.reset lub Achievements.resetAll z interfejsów API zarządzania.

Tabele wyników

Zapoznaj się z przewodnikiem po tabelach wyników, który zawiera bardziej szczegółowe informacje.

  • Chcesz zobaczyć listę wszystkich tablic wyników w grze? Wezwij stronę Tabele wyników.list.
  • Czy gracz kończy grę? Możesz przesłać ich wynik do usługi Scores.submit i sprawdzić, czy jest to nowy rekord.
  • Chcesz wyświetlić tabelę wyników? Pobierz dane z pliku Scores.list i pokaż je użytkownikowi.
  • Użyj narzędzia Scores.listWindow, aby znaleźć zbiór wyników bliskich najwyższego wyniku użytkownika.
  • Aby uzyskać więcej informacji o wyniku gracza w określonej tabeli wyników (np. jeśli należy on do 12% najlepszych zawodników), wywołaj Scores.get.
  • Czy debugujesz grę? Spróbuj wywołać Scores.reset w interfejsach API zarządzania, aby zresetować wszystkie wyniki tego gracza z określonej tabeli wyników.