Posted by Wolff Dobson, Developer Advocate
We’re taking steps to reduce sign-in friction and unnecessary permission requests for players by moving the Games APIs to a new model. The new interaction is:
- Players are prompted to sign-in once per account, rather than once per game
- Players no longer need their account upgraded to Google+ to use Play Games services
- Once players have signed-in for the first time, they will no longer need to sign in to any future games; they will be automatically signed in
- Note: Players can turn off auto-sign-in through the Play Games App’s settings
- Once a user signs in for first time, new games will generally be able to sign in without any user interaction
- There is no consent screen required for signing in on any particular game. Sign-in will be automatic to each new game.
In order to respect user’s privacy and avoid revealing their real name, we also have to change the way player IDs work.
- For existing players: Games will continue to get their Google+ ID (also called “player ID” in previous documentation) when they sign in.
- For new players: Games will get a new player ID which is not the same as the previous IDs we’ve used.
Potential issues
Most games should see no interruption or change in service. There are a handful of cases, however, where some change is required.
Below are some issues, along with potential solutions.
These are:
- Asking for the Google+ scope unnecessarily
- Issue: Your users will get unnecessary, potentially disturbing pop-up consent windows
- Solution: Don’t request any additional scopes unless you absolutely need them
- Using the Play Games player ID for other Google APIs that are not games
- Issue: You will not get valid data back from these other endpoints.
- Solution: Don’t use player ID for other Google APIs.
- Using mobile/client access tokens on the server
- Issue: Your access token may not contain the information you’re looking for
- ...and this is not recommended in the first place.
- Solution: Use the new GetServerAuthCode API instead.
- Issue: Your access token may not contain the information you’re looking for
Let’s cover each of these issues in detail.
Issue: Asking for unnecessary scopes
Early versions of our samples and documentation created a GoogleApiClient as follows:
// Don’t do it this way!
GoogleApiClient gac = new GoogleApiClient.Builder(this, this, this)
.addApi(Games.API)
.addScope(Plus.SCOPE_PLUS_LOGIN) // The bad part
.build();
// Don’t do it this way!
In this case, the developer is specifically requesting the plus.login scope. If you ask for plus.login, your users will get a consent dialog.
Solution: Ask only for the scopes you need
Remove any unneeded scopes from your GoogleApiClient construction along with any APIs you no longer use.
// This way you won’t get a consent screen
GoogleApiClient gac = new GoogleApiClient.Builder(this, this, this)
.addApi(Games.API)
.build();
// This way you won’t get a consent screen
For Google+ users
If your app uses specific Google+ features, such as requiring access to the player’s real-world Google+ social graph, be aware that new users will still be required to have a G+ profile to use your game. (Existing users who have already signed in won’t be asked to re-consent).
To require Google+ accounts to use your game, change your Games.API declaration to the following:
.addApi(Games.API, new GamesOptions.Builder()
.setRequireGooglePlus(true).build())
This will ensure that your game continues to ask for the necessary permissions/scopes to continue using the player’s real-world social graph and real name profile.
Issue: Using the Player ID as another ID
If you call the Games.getCurrentPlayerId() API, the value returned here is the identifier that Games uses for this player.
Traditionally, this value could be passed into other APIs such as Plus.PeopleApi.load. In the new model, this is no longer the case. Player IDs are ONLY valid for use with Games APIs.
Solution - Don’t mix IDs
The Games APIs (those accessed from com.google.android.gms.games) all use the Player ID, and as long as you use only those, they are guaranteed to work with the new IDs.
Issue: Using mobile/client access tokens on the server
A common pattern we’ve seen is:
- Use GoogleAuthUtil to obtain an access token
- Send this token to a server
- On the server, call Google to verify the authenticity. This is most commonly done by calling http://ift.tt/1grrjJM and looking at the response
This is not recommended in the first place, and is even more not-recommended after the shift in scopes.
Reasons not to do this:
- It requires your app to know the current account the user is using, which requires holding the GET_ACCOUNTS permission. On Android M, this will result in the user being asked to share their contacts with your app at runtime, which can be intimidating.
- The tokeninfo endpoint isn’t really designed for this use case - it’s primarily designed as a debugging tool, not as a production API. This means that you may be rate limited in the future if you call this API.
- The user_id returned by token info may no longer be present with the new model. And even if it is present, the value won’t be the same as the new player ID. (See problem 2 above)
- The token could expire at any time (access token expiration times are not a guarantee).
- Using client tokens on the server require extra validation checks to make sure the token is not granted to a different application.
Solution: Use the new GetServerAuthCode flow
Fortunately, the solution is known, and is basically the same as our server-side auth recommendations for web.
-
Upgrade to the latest version of Google Play Services SDK - at least 8.4.87.
-
Create a server client ID if you don’t already have one
-
Go to the Google Developer Console, and select your project
-
From the left nav, select API Manager, then select Credentials
-
Select “New Credentials” and choose “OAuth Client ID”
-
Select “Web Application” and name it something useful for your application
-
The client id for this web application is now your server client id.
-
-
In your game, connect your GoogleApiClient as normal.
-
Once connected, call the following API:
-
Games.getGamesServerAuthCode(googleApiClient, “your_server_client_id”)
-
If you were using GoogleAuthUtil before, you were probably calling this on a background thread - in which case the code looks like this:
-
// Good way
{
GetServerAuthCodeResult result =
Games.getGamesServerAuthCode(gac, clientId).await();
if (result.isSuccess()) {
String authCode = result.getCode();
// Send code to server.
}
}
// Good way
-
Upgrade to the latest version of Google Play Services SDK - at least 8.4.87.
-
Create a server client ID if you don’t already have one
-
Go to the Google Developer Console, and select your project
-
From the left nav, select API Manager, then select Credentials
-
Select “New Credentials” and choose “OAuth Client ID”
-
Select “Web Application” and name it something useful for your application
-
The client id for this web application is now your server client id.
-
-
In your game, connect your GoogleApiClient as normal.
-
Once connected, call the following API:
-
Games.getGamesServerAuthCode(googleApiClient, “your_server_client_id”)
-
If you were using GoogleAuthUtil before, you were probably calling this on a background thread - in which case the code looks like this:
-
// Good way
{
GetServerAuthCodeResult result =
Games.getGamesServerAuthCode(gac, clientId).await();
if (result.isSuccess()) {
String authCode = result.getCode();
// Send code to server.
}
}
// Good way
-
Send the auth code to your server, exactly the same as before.
-
On your server, make an RPC to http://ift.tt/1GDfmSD to exchange the auth code for an access token, probably using a Google Apis Client Library.
-
You’ll have to provide the server client ID, server client secret (listed in the Developer Console when you created the server client ID), and the auth code.
-
See more details here: http://ift.tt/1NfsVeZ
-
No, really: You should use a Google Apis Client Library to make this process easier.
-
-
Once you have the access token, you can now call http://ift.tt/1SE6Sji using that access token.
-
Pass the auth token in a header as follows:
-
“Authorization: OAuth <access_token>”
-
-
The response value will contain the player ID for the user. This is the correct player ID to use for this user.
-
This access token can be used to make additional server-to-server calls as needed.
-
In summary
Let’s be very clear: If you do nothing, unless you are depending explicitly on Google+ features, you will see no change in functionality, and a smoother sign-in experience.
If you are:
- Requesting Google+ scopes without using them, it’s a good idea to stop using them from here out.
- Sending client access tokens to your server, we strongly suggest you use getGamesServerAuthCode() instead.
Thanks, and keep making awesome games!