Включение серверного доступа к игровым сервисам Google Play

Мы рекомендуем вам аутентифицировать игроков и безопасно передавать личность игрока на внутренний сервер. Это позволяет вашей игре безопасно получать идентификационные данные игрока и другие данные, не подвергаясь потенциальному вмешательству при прохождении через устройство.

В этом сценарии после успешного входа игрока вы можете запросить специальный одноразовый код (называемый кодом аутентификации сервера ) из Play Games Services v2 SDK, который клиент передает на сервер. Затем на сервере замените код аутентификации сервера на токен OAuth 2.0, который сервер может использовать для вызовов API игровых сервисов Google Play.

Дополнительные инструкции по добавлению входа в свои игры см. в разделе Вход в игры для Android .

Для автономного доступа необходимо выполнить следующие действия:

  1. В консоли Google Play: создайте учетные данные для своего игрового сервера. Тип клиента OAuth для учетных данных будет «веб».
  2. В приложении для Android: при входе запросите код аутентификации сервера для учетных данных вашего сервера и передайте его на свой сервер.
  3. На игровом сервере: обменяйте код аутентификации сервера на токен доступа OAuth с помощью сервисов аутентификации Google, а затем используйте его для вызова API REST игровых сервисов Play .

Прежде чем вы начнете

Сначала вам нужно добавить свою игру в консоль Google Play , как описано в разделе Настройка игровых сервисов Google Play , и интегрировать вход в игровые сервисы Play с вашей игрой.

Создайте связанное веб-приложение на стороне сервера для вашей игры.

Игровые сервисы Google Play не обеспечивают серверную поддержку веб-игр. Тем не менее, он обеспечивает поддержку внутреннего сервера для сервера вашей игры для Android.

Если вы хотите использовать REST API для сервисов Google Play Games в своем серверном приложении, выполните следующие действия:

  1. В игре в Google Play Console перейдите в раздел «Игровые сервисы Play» > «Настройка и управление» > «Конфигурация» .
  2. Выберите Добавить учетные данные , чтобы перейти на страницу Добавить учетные данные . Выберите «Игровой сервер» в качестве типа учетных данных и перейдите к разделу «Авторизация» .
    1. Если на вашем игровом сервере уже есть идентификатор клиента OAuth, выберите его в раскрывающемся меню. После сохранения изменений перейдите к следующему разделу .
    2. Если у вас нет существующего идентификатора клиента OAuth для вашего игрового сервера, вы можете его создать.
      1. Нажмите «Создать клиент OAuth» и перейдите по ссылке «Создать идентификатор клиента OAuth» .
      2. Вы перейдете на страницу создания идентификатора клиента OAuth Google Cloud Platform для связанного с вашей игрой проекта Cloud Platform.
      3. Заполните форму страницы и нажмите «Создать». Обязательно установите Тип приложения на Веб-приложение.
      4. Вернитесь в раздел «Авторизация» на странице «Добавить учетные данные» , выберите только что созданный клиент OAuth и сохраните изменения.

Получить код авторизации сервера

Чтобы получить код аутентификации сервера, который ваша игра может использовать для токенов доступа на вашем внутреннем сервере:

  1. Вызовите requestServerSideAccess от клиента.

    1. Убедитесь, что вы используете идентификатор клиента OAuth, зарегистрированный для вашего игрового сервера , а не идентификатор клиента OAuth вашего приложения для Android.
    2. (Необязательно) Если вашему игровому серверу требуется автономный доступ (длительный доступ с использованием токена обновления) к игровым сервисам Play, вы можете установить для параметра forceRefreshToken значение true.
    GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(this);
    gamesSignInClient
      .requestServerSideAccess(OAUTH_2_WEB_CLIENT_ID, /* forceRefreshToken= */ false)
      .addOnCompleteListener( task -> {
        if (task.isSuccessful()) {
          String serverAuthToken = task.getResult();
          // Send authentication code to the backend game server to be
          // exchanged for an access token and used to verify the player
          // via the Play Games Services REST APIs.
        } else {
          // Failed to retrieve authentication code.
        }
    });
    
  2. Отправьте токен кода аутентификации OAuth на внутренний сервер, чтобы его можно было обменять, идентификатор игрока сверился с API REST сервисов Play Games, а затем прошел аутентификацию в вашей игре.

Обмен кода авторизации сервера на токен доступа на сервере

Отправьте код аутентификации сервера на внутренний сервер для обмена на токены доступа и обновления. Используйте токен доступа для вызова API игровых сервисов Google Play от имени игрока и, при необходимости, сохраните токен обновления, чтобы получить новый токен доступа по истечении срока действия токена доступа.

В следующем фрагменте кода показано, как можно реализовать серверный код на языке программирования Java для обмена кода аутентификации сервера на токены доступа. Он использует образец приложения 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;
}

Вызов REST API с сервера

Полное описание доступных вызовов API см. в разделе REST API для сервисов Google Play Games .

Примеры вызовов REST API, которые могут оказаться полезными, включают следующее:

Игрок

  • Хотите получить идентификатор и данные профиля вошедшего в систему игрока? Позвоните в Players.get , указав 'me' в качестве идентификатора.

Друзья

Обязательно просмотрите руководство «Друзья» , в котором более подробно рассказывается о программе «Друзья».

  • Хотите получить список друзей игрока? Вызовите Players.list с 'friends_all' в качестве collection .
  • Проверьте, есть ли у вас доступ к списку друзей? Позвоните me в Players.get и посмотрите в ответе поле profileSettings.friendsListVisibility .

Достижения

Обязательно ознакомьтесь с руководством по достижениям , в котором достижения описаны более подробно.

  • Хотите получить список текущих достижений? Вы можете позвонить в AchievementDefinitions.list .
  • Объедините это с вызовом Achievements.list , чтобы узнать, какие из них разблокировал игрок.
  • Игрок заработал достижение? Используйте Achievements.unlock , чтобы разблокировать его!
  • Достиг ли игрок частичного достижения? Используйте Achievements.increment , чтобы сообщить о прогрессе (и узнать, разблокировал ли его игрок).
  • Вы отлаживаете игру, которая еще не запущена? Попробуйте вызвать Achievements.reset или Achievements.resetAll из API управления, чтобы сбросить достижения в исходное состояние.

Таблицы лидеров

Обязательно ознакомьтесь с руководством по таблицам лидеров , в котором таблицы лидеров описаны более подробно.

  • Хотите получить список всех табло в игре? Позвоните в Leaderboards.list .
  • Игрок закончил игру? Вы можете отправить их результаты на Scores.submit и узнать, является ли это новым рекордом.
  • Хотите отобразить таблицу лидеров? Получите данные из Scores.list и покажите их пользователю.
  • Используйте Scores.listWindow , чтобы найти набор оценок, близких к наивысшему результату пользователя.
  • Чтобы получить дополнительные сведения о счете игрока в определенной таблице лидеров (например, если игрок входит в число 12 % лучших игроков), вызовите Scores.get .
  • Вы отлаживаете игру? Попробуйте вызвать Scores.reset из API управления, чтобы сбросить все баллы для этого игрока из определенной таблицы лидеров.