Serverseitigen Zugriff auf die Google Play-Spieldienste aktivieren

Wenn Ihr Spiel einen Backend-Server verwendet, empfehlen wir Ihnen, Google Log-in zu verwenden, um Spieler zu authentifizieren und die Identität des Spielers sicher an den Backend-Server weiterzuleiten. Auf diese Weise kann Ihr Spiel außerdem die Identität des Spielers und andere Daten sicher abrufen, ohne potenziellen Manipulationen ausgesetzt zu sein, während es das Gerät durchläuft.

In diesem Szenario wird der Spieler vom Spiel aufgefordert, sich wie gewohnt in den Google Play-Spieldiensten anzumelden. Wenn sich der Spieler erfolgreich anmeldet, enthält das GoogleSignInAccount-Objekt einen speziellen Einmalcode (Server-Authentifizierungscode), den der Client an den Server weitergibt. Tauschen Sie dann auf dem Server den Serverautorisierungscode gegen ein OAuth 2.0-Token aus, mit dem der Server Aufrufe an die Google Play-Spieldienste API ausführen kann.

Weitere Informationen zum Hinzufügen einer Anmeldung in Ihren Spielen finden Sie unter Anmeldung in Android-Spielen.

Ein detailliertes Codebeispiel zur Authentifizierung von Spielern mit Google Sign-In finden Sie im clientserverskeleton-Beispiel auf GitHub.

Für den Offlinezugriff sind die folgenden Schritte erforderlich:

  1. In der Google Play Console: Erstellen Sie Anmeldedaten für Ihren Gameserver. Der OAuth-Clienttyp der Anmeldedaten ist „web“.
  2. In der Android-App: Fordere bei der Anmeldung einen Serverauthentifizierungscode für die Anmeldedaten deines Servers an und leite ihn an deinen Server weiter.
  3. Auf Ihrem Gameserver: Tauschen Sie den Serverautorisierungscode mithilfe der Google Auth-Dienste gegen ein OAuth-Zugriffstoken aus und rufen Sie dann die REST APIs der Play-Spieldienste damit auf.

Hinweis

Bevor Sie Google Sign-In in Ihr Spiel einbinden können, müssen Sie es zuerst in der Google Play Console hinzufügen, wie im Abschnitt Google Play-Spieldienste einrichten beschrieben.

Eine zugehörige serverseitige Webanwendung für Ihr Spiel erstellen

Die Google Play-Spieldienste bieten keinen Back-End-Support für Webspiele. Es bietet jedoch Back-End-Server-Support für den Server Ihres Android-Spiels.

Wenn Sie die REST APIs für Google Play-Spieldienste in Ihrer serverseitigen App verwenden möchten, gehen Sie so vor:

  1. Erstellen Sie in der Google Play Console im Bereich Verknüpfte Apps eine zugehörige Webanwendung für Ihr Spiel. Hinweis: launch_url wird für diesen Ablauf nicht verwendet und kann leer gelassen werden.
  2. So rufen Sie die Anmeldedaten für Ihre Anwendung ab:
    1. Klicken Sie in der Google Play Console unter Ihrem Spiel auf Spieldetails.
    2. Scrollen Sie nach unten zum Abschnitt API Console-Projekt und klicken Sie auf den Link zum API Console-Projekt.
    3. Laden Sie in der Google API Console auf dem Bildschirm APIs und Dienste > Anmeldedaten die Datei client_secret.json für Ihre Webanwendung herunter und speichern Sie sie an einem Speicherort, auf den Ihr Server zugreifen kann. Notieren Sie sich die Client-ID der Anmeldedaten für später.
  3. Starte deine serverseitige App neu, damit sie Anfragen von der Client-App deines Spiels annehmen kann.

Auf dem Client anmelden

Die Klasse GoogleSignInClient ist der Haupteinstiegspunkt, um das Konto des aktuell angemeldeten Spielers abzurufen und ihn anzumelden, falls er sich noch nicht in deiner App auf dem Gerät angemeldet hat.

So erstellen Sie einen Anmeldeclient:

  1. Erstelle einen Anmeldeclient über das Objekt GoogleSignInOptions. Geben Sie unter GoogleSignInOptions.Builder für die Anmeldung GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN an.
  2. Sie müssen auch angeben, dass für Ihr Spiel ein Authentifizierungscode für Ihren Backend-Server erforderlich ist. Rufen Sie dazu die Methode GoogleSignInOptions.Builder.requestServerAuthCode() mit der Client-ID des Servers als Parameter auf. Den Autorisierungscode für Zugriffstokens auf deinem Back-End-Server wirst du später abrufen, wie unter Server-Authentifizierungscode abrufen beschrieben.
  3. Rufen Sie die Methode GoogleSignIn.getClient() auf und übergeben Sie die zuvor konfigurierten Optionen. Wenn der Aufruf erfolgreich ist, gibt die Google Sign-In API eine Instanz von GoogleSignInClient zurück.
  4. Nachdem du die Instanz GoogleSignInClient abgerufen hast, solltest du den Spieler wie unter Lautlose Anmeldung ausführen beschrieben über die onResume() der Aktivität stumm anmelden.

Beispiel:

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);
}

Serverauthentifizierungscode abrufen

Wenn Sie einen Serverautorisierungscode abrufen möchten, den Ihr Spiel für Zugriffstokens auf Ihrem Backend-Server verwenden kann, rufen Sie die getServerAuthCode()-Methode auf dem GoogleSignInAccount-Objekt auf, das Google Sign-In bei erfolgreicher Spieleranmeldung zurückgibt.

Beispiel:

// 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();
    }
  }
}

Serverautorisierungscode gegen ein Zugriffstoken auf dem Server austauschen

Sende den Serverautorisierungscode an deinen Backend-Server, um ihn gegen Zugriffs- und Aktualisierungstokens einzutauschen. Verwenden Sie das Zugriffstoken, um die Google Play Games Services API im Namen des Spielers aufzurufen. Optional können Sie das Aktualisierungstoken speichern, um nach Ablauf des Zugriffstokens ein neues Zugriffstoken zu erhalten.

Im folgenden Code-Snippet wird gezeigt, wie Sie den serverseitigen Code in der Programmiersprache Java implementieren können, um den Serverauthentifizierungscode gegen Zugriffstokens einzutauschen. Dabei wird die Beispielanwendung „clientserverskeleton“ verwendet:

/**
 * 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;
}

Weitere Informationen zum Zugriff auf Google APIs über einen Back-End-Server im Namen eines angemeldeten Spielers finden Sie unter Serverseitigen Zugriff aktivieren.

Abmeldung von Spielern verarbeiten

Wenn du Spieler von deinem Spiel abmelden möchtest, rufe die Methode signOut() für GoogleSignInClient auf. Ein Beispiel für ein Code-Snippet findest du unter Player abmelden.

REST APIs vom Server aufrufen

Eine vollständige Beschreibung der verfügbaren API-Aufrufe finden Sie unter REST APIs für Google Play Spieledienste.

Hier einige Beispiele für REST API-Aufrufe, die für Sie interessant sein könnten:

Spieler

  • Möchtest du die ID und die Profildaten des angemeldeten Spielers abrufen? Rufe Players.get mit 'me' als ID auf.

Friends

Weitere Informationen zu Freunden findest du im Hilfeartikel Freunde.

Erfolge

Weitere Informationen zu den Erfolgen findest du im Hilfeartikel Erfolge.

  • Möchtest du eine Liste deiner aktuellen Erfolge aufrufen? Rufen Sie dazu AchievementDefinitions.list auf.
  • Kombinieren Sie dies mit einem Aufruf von Achievements.list, um herauszufinden, welche der Spieler freigeschaltet haben.
  • Hat der Spieler einen Erfolg erzielt? Verwende Achievements.unlock, um ihn freizuschalten.
  • Hat der Spieler Fortschritte bei einem Teilerfolg gemacht? Verwende Achievements.increment, um den Fortschritt zu melden und herauszufinden, ob der Spieler den Erfolg freigeschaltet hat.
  • Entwickeln Sie ein Spiel, das noch nicht in der Produktion ist? Rufe Achievements.reset oder Achievements.resetAll aus den Verwaltungs-APIs auf, um die Erfolge auf den ursprünglichen Zustand zurückzusetzen.

Bestenlisten

In der Anleitung zu Bestenlisten finden Sie weitere Informationen zu Bestenlisten.

  • Möchten Sie eine Liste aller Punktestände in dem Spiel abrufen? Rufe Leaderboards.list auf.
  • Ist der Spieler mit einem Spiel fertig? Sie können die Punktzahl an Scores.submit senden und so herausfinden, ob es sich um einen neuen Highscore handelt.
  • Möchten Sie eine Bestenliste anzeigen lassen? Rufen Sie die Daten aus Punkteliste.txt ab und zeigen Sie sie dem Nutzer an.
  • Mit Scores.listWindow kannst du eine Auswahl von Punktzahlen finden, die dem Highscore des Nutzers nahekommen.
  • Wenn Sie weitere Informationen zum Punktestand eines Spielers in einer bestimmten Bestenliste erhalten möchten (z. B. ob er zu den besten 12% aller Spieler gehört), rufen Sie Scores.get auf.
  • Entwickeln Sie ein Spiel? Rufen Sie Scores.reset aus den Management APIs auf, um alle Punkte für diesen Spieler aus einer bestimmten Bestenliste zurückzusetzen.