Activer l'accès côté serveur aux services de jeux Google Play

Si votre jeu utilise un serveur backend, nous vous recommandons d'utiliser Google Sign-In pour authentifier les joueurs et transmettre leur identité au serveur backend de manière sécurisée. Cela permet également à votre jeu de récupérer de manière sécurisée l'identité du joueur et d'autres données sans être exposé à des tentatives de falsification lors de son passage sur l'appareil.

Dans ce scénario, votre jeu invite le joueur à se connecter aux services de jeux Google Play comme d'habitude. Lorsque le joueur se connecte, l'objet GoogleSignInAccount contient un code à usage unique spécial (appelé code d'autorisation du serveur) que le client transmet au serveur. Ensuite, sur le serveur, échangez le code d'autorisation du serveur contre un jeton OAuth 2.0 permettant au serveur d'appeler l'API des services de jeux Google Play.

Pour obtenir des conseils supplémentaires sur l'ajout de la connexion dans vos jeux, consultez Se connecter dans les jeux Android.

Pour obtenir un exemple de code détaillé montrant comment utiliser Google Sign-In pour authentifier les joueurs, consultez l'exemple clientserverskeleton sur GitHub.

Pour utiliser l'accès hors connexion, procédez comme suit :

  1. Dans la Google Play Console, créez des identifiants pour votre serveur de jeu. Le type de client OAuth pour ces identifiants est "web".
  2. Dans l'application Android : lors de la procédure de connexion, demandez un code d'autorisation pour les identifiants de votre serveur et transmettez-les lui.
  3. Sur votre serveur de jeu: échangez le code d'autorisation du serveur contre un jeton d'accès OAuth à l'aide des services d'authentification Google, puis utilisez-le pour appeler les API REST des services de jeux Play.

Avant de commencer

Avant de pouvoir intégrer la connexion Google à votre jeu, vous devez d'abord ajouter votre jeu dans la Google Play Console, comme décrit dans la section Configurer les services de jeux Google Play.

Créer une application Web côté serveur associée à votre jeu

Les services de jeux Google Play ne proposent pas de backend pour les jeux Web. Toutefois, un serveur backend est disponible pour le serveur de votre jeu Android.

Si vous souhaitez utiliser les API REST pour les services de jeux Google Play dans votre application côté serveur, procédez comme suit :

  1. Créez une application Web associée pour votre jeu dans la section Applications associées de la Google Play Console. Notez que launch_url n'est pas utilisé pour ce flux et peut être laissé vide.
  2. Pour obtenir les informations d'identification de votre application, procédez comme suit :
    1. Dans la Google Play Console, accédez à votre jeu, puis cliquez sur Détails du jeu.
    2. Faites défiler la page jusqu'à la section Projet dans la console API, puis cliquez sur le lien vers le projet dans la console API.
    3. Sur l'écran APIs & Services > Credentials (API et services > Identifiants) de la console de l'API Google, téléchargez le fichier client_secret.json pour votre application Web et enregistrez-le à un emplacement auquel votre serveur peut accéder. Enregistrez l'ID client des identifiants pour référence ultérieure.
  3. Redémarrez votre application côté serveur pour qu'elle soit prête à accepter les requêtes de l'application cliente de votre jeu.

Se connecter sur le client

La classe GoogleSignInClient est le point d'entrée principal pour récupérer le compte du joueur actuellement connecté et pour le connecter s'il ne l'a pas déjà fait sur votre application sur l'appareil.

Pour créer un client de connexion, procédez comme suit:

  1. Créez un client de connexion via l'objet GoogleSignInOptions. Dans GoogleSignInOptions.Builder, pour configurer votre connexion, vous devez spécifier GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN.
  2. Vous devez également spécifier que votre jeu nécessite un code d'autorisation pour votre serveur backend en appelant la méthode GoogleSignInOptions.Builder.requestServerAuthCode() avec l'ID client du serveur comme paramètre. Vous récupérerez le code d'autorisation plus tard pour les jetons d'accès sur votre serveur backend, comme décrit dans la section Obtenir le code d'autorisation du serveur.
  3. Appelez la méthode GoogleSignIn.getClient() et transmettez les options que vous avez précédemment configurées. Si l'appel aboutit, l'API Google Sign-In renvoie une instance de GoogleSignInClient.
  4. Une fois que vous avez obtenu l'instance GoogleSignInClient, vous devez procéder à la connexion silencieuse du joueur à partir du onResume() de l'activité, comme décrit dans la section Effectuer une connexion silencieuse.

Exemple :

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

Obtenir le code d'autorisation du serveur

Pour récupérer un code d'autorisation de serveur que votre jeu peut utiliser pour les jetons d'accès sur votre serveur backend, appelez la méthode getServerAuthCode() sur l'objet GoogleSignInAccount renvoyé par la connexion Google une fois le joueur connecté.

Exemple :

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

Échanger le code d'autorisation du serveur contre un jeton d'accès sur le serveur

Envoyez le code d'autorisation du serveur à votre serveur backend pour l'échanger contre des jetons d'accès et d'actualisation. Utilisez le jeton d'accès pour appeler l'API Google Play Jeux Services au nom du joueur et, éventuellement, stockez le jeton d'actualisation pour acquérir un nouveau jeton d'accès lorsque le jeton existant expirera.

L'extrait de code suivant montre comment implémenter le code côté serveur dans le langage de programmation Java afin d'échanger le code d'autorisation du serveur contre des jetons d'accès. Il utilise l'application exemple 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;
}

Pour en savoir plus sur l'accès aux API Google à partir d'un serveur backend pour le compte d'un joueur connecté, consultez la section Activer l'accès côté serveur.

Gérer la déconnexion des joueurs

Pour déconnecter les joueurs de votre jeu, appelez la méthode signOut() sur GoogleSignInClient. Pour obtenir un exemple d'extrait de code, consultez la section Déconnexion du lecteur.

Appeler des API REST à partir du serveur

Pour obtenir une description complète des appels d'API disponibles, consultez la page API REST pour les services Google Play Jeux.

Voici des exemples d'appels d'API REST qui peuvent vous être utiles :

Joueur

  • Si vous souhaitez obtenir l'ID du joueur connecté et les données de son profil, Appelez Players.get avec 'me' comme ID.

Amis

Consultez le guide Amis pour en savoir plus.

Succès

Consultez le guide sur les succès pour en savoir plus.

  • Vous souhaitez obtenir la liste des récompenses actuelles ? Vous pouvez appeler AchievementDefinitions.list.
  • Combinez cela avec un appel à Achievements.list pour identifier les récompenses que le joueur a déverrouillées.
  • Le joueur a-t-il obtenu un succès ? Utilisez Achievements.unlock pour le déverrouiller.
  • Le joueur a-t-il progressé vers un succès partiel ? Utilisez Achievements.increment pour signaler la progression (et déterminer si le joueur l'a déverrouillée).
  • Déboguez-vous un jeu qui n'est pas encore en production ? Essayez d'appeler Achievements.reset ou Achievements.resetAll à partir des API de gestion pour rétablir leur état d'origine.

Classements

Veillez à consulter le guide sur les classements, qui explique plus en détail ce type de fonctionnalité.

  • Si vous voulez obtenir la liste de tous les classements dans le jeu, Appelez Leaderboards.list.
  • Le joueur a-t-il terminé une partie ? Vous pouvez envoyer son score à Scores.submit et découvrir s'il s'agit d'un nouveau record.
  • Vous souhaitez afficher un classement ? Récupérez les données de Scores.list et présentez-les à l'utilisateur.
  • Utilisez Scores.listWindow pour trouver une variété de scores proches du record de l'utilisateur.
  • Pour obtenir plus d'informations sur le score d'un joueur dans un classement spécifique (par exemple, si le joueur figure dans la tranche supérieure de 12% de tous les joueurs), appelez Scores.get.
  • Déboguez-vous un jeu ? Essayez d'appeler Scores.reset à partir des API Management pour réinitialiser tous les scores du joueur à partir d'un classement donné.