Enabling Server-Side Access to Google Play Games Services

If your game uses a backend server, we recommend that you use Google Sign-In to authenticate players and securely pass the player's identity to the backend server.

In this scenario, your game prompts the player to sign in to Google Play games services as usual. When the player signs in successfully, the GoogleSignInAccount object contains a special single-use code (called the server auth code) that the client passes to the server. Then, on the server, exchange the server auth code for an OAuth 2.0 token that the server can use to make calls to the Google Play Games Services API.

For additional guidance on adding sign-in in your games, see Sign-in in Android Games.

To see a detailed code sample showing how to use Google Sign-In to authenticate players, see the clientserverskeleton sample on GitHub.

Before you begin

Before you can integrate Google Sign-In into your game, you'll first need to add your game in the Google Play Console, as described in Setting Up Google Play Games Services.

Performing sign-in on the client

The GoogleSignInClient class is the main entry point to retrieve the account of the currently signed-in player, and to sign-in the player if they have not previously done so on your app in the device.

To create a sign-in client, follow these steps:

  1. Create a sign-in client via the GoogleSignInOptions object. In the GoogleSignInOptions.Builder to configure your sign-in, you must specify GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN.
  2. You must also specify that your game requires an auth code for your backend server by calling the GoogleSignInOptions.Builder.requestServerAuthCode() method with server's client ID as the parameter. You will retrieve the auth code later for access tokens on your backend server, as described in Get the server auth code.
  3. Call the GoogleSignIn.getClient() method and pass in options you previously configured. If the call is successful, Google Sign-In API returns an instance of GoogleSignInClient.
  4. Once you have obtained the GoogleSignInClient instance, you should proceed to sign the player in silently from the activity’s onResume(), as described in Performing silent sign-in.

Here's an example:

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

Create an associated web app for your game

If you want to use the REST APIs for Google Play Games services in your server-side app, follow these steps:

  1. Create an associated web app for your game in the Linked Apps section of the Google Play Console.
  2. Set the launch URL field with the url to access your server-side app.
  3. To get the credential information for your app:
    1. From your game in the Google Play Console, click Game Details.
    2. Scroll down to the API Console Project section and click on the link to the API console project.
    3. From the credentials screen in the Google API Console, download the client_secret.json file for your web app and save it in a location that your server can access.
  4. Restart your server-side app so it’s ready to accept requests from your game’s client app.

To learn more about calling Google REST APIs, see Authorizing and Using REST APIs.

Get the server auth code

To retrieve a server auth code that your game can use for access tokens on your backend server, call the getServerAuthCode() method on the GoogleSignInAccount object that Google Sign-In returns on successful player sign-in.

Here's an example:


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

Exchange the server auth code for an access token on the server

Send the server auth code to your backend server to exchange for access and refresh tokens. Use the access token to call the Google Play Games Services API on behalf of the player and, optionally, store the refresh token to acquire a new access token when the access token expires.

The following code snippet shows how you might implement the server-side code in the Java programming language to exchange the server auth code for access tokens.

/**
 * 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://www.googleapis.com/oauth2/v4/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;
}

To learn more about accessing Google APIs from a backend server on behalf of a signed-in player, see Enabling Server-Side Access.

Handle player sign-out

To sign players out of your game, call the signOut() method on the GoogleSignInClient. For an example code snippet, see Signing the player out.

Enviar comentarios sobre…

Play Games Services for Android
Play Games Services for Android