Recomendamos que você use GamesSignInClient para autenticar jogadores e transmitir com segurança a identidade do jogador para o servidor de back-end. Isso permite que o jogo recupere a identidade do jogador e outros dados de maneira segura, sem estar exposto a possíveis adulterações durante a transmissão pelo dispositivo.
Quando o jogador faz o login, é possível solicitar um código de uso único especial (chamado de código de autenticação do servidor) do SDK dos serviços relacionados a jogos do Google Play v2, que o cliente transmite para o servidor. Depois, no servidor, troque o código de autenticação por um token OAuth 2.0 que o servidor pode usar para fazer chamadas para a API Google Play Games Services.
Para ver outras orientações sobre como adicionar login nos seus jogos, consulte Login para jogos no Android.
Siga estas etapas para acesso off-line:
- No Google Play Console: crie uma credencial para seu servidor de jogos. O tipo de cliente OAuth da credencial será "Web".
- No app Android: como parte do login, solicite um código de autenticação para a
credencial do seu servidor e transmita-o para ele. O
GamesSigninClient
pode solicitar três escopos do OAuth 2.0 ao solicitar acesso do lado do servidor às APIs da Web dos Serviços relacionados a jogos do Google Play. Os escopos opcionais sãoEMAIL
,PROFILE
eOPEN_ID
. Os dois escopos padrão sãoDRIVE_APPFOLDER
eGAMES_LITE
. - No servidor de jogos: troque o código de autenticação por um token de acesso OAuth usando os serviços de autenticação do Google. Depois, use-o para chamar as APIs REST dos serviços relacionados a jogos do Google Play.
Antes de começar
Primeiro, adicione seu jogo ao Google Play Console, conforme descrito em Configurar os serviços relacionados a jogos do Google Play. Depois, faça a integração do Login nos serviços relacionados a jogos do Google Play ao seu jogo.
Criar um app da Web do lado do servidor
Os serviços relacionados a jogos do Google Play não oferecem suporte de back-end para jogos na Web. No entanto, eles oferecem suporte do servidor de back-end para o servidor do seu jogo Android.
Se você quiser usar as APIs REST para serviços do Google Play Games no seu app do lado do servidor, siga estas etapas:
- No Google Play Console, selecione um jogo.
- Acesse Serviços relacionados a jogos do Google Play > Configuração e gerenciamento > Configuração.
- Selecione Adicionar credencial para acessar a página Adicionar credencial.
Selecione Servidor de jogos como o tipo de credencial e siga para a
seção Autorização.
- Se o servidor de jogos já tiver um ID do cliente OAuth, selecione-o no menu suspenso. Depois de salvar as mudanças, siga para a próxima seção.
- Você pode criar um ID do cliente OAuth se ainda não tiver um.
- Clique em Criar um cliente OAuth e siga o link Criar ID do cliente OAuth.
- Isso leva você à página Criar ID do cliente OAuth do Google Cloud Platform do projeto associado ao jogo.
- Preencha o formulário da página e clique em "Criar". Defina o tipo de aplicativo como "aplicativo da Web".
- Volte para a seção Autorização da página "Adicionar credencial", selecione o cliente OAuth recém-criado e salve as mudanças.
Receber o código de autenticação do servidor
Para recuperar um código de autenticação do servidor que o jogo possa usar para tokens de acesso no servidor de back-end:
Chame
requestServerSideAccess
do cliente.- Use o ID do cliente OAuth registrado para o servidor do jogo, e não o ID do cliente OAuth do app Android.
- Opcional: caso o servidor do jogo exija acesso off-line (acesso de longa
duração usando um token de atualização) para os Serviços relacionados a jogos do Google Play, defina o
parâmetro
forceRefreshToken
como verdadeiro. (Opcional) Como parte do login, os novos usuários vão encontrar uma única tela de consentimento para outros escopos. Ao aceitar o consentimento, você define o parâmetro
scopes
com os escopos do OAuthEMAIL
,PROFILE
eOPEN_ID
. Se os usuários recusarem o consentimento, apenas os dois escopos padrãoDRIVE_APPFOLDER
eGAMES_LITE
serão enviados ao back-end.Tela de consentimento para outros escopos do OAuth. Clique para ampliar. GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(this); gamesSignInClient.requestServerSideAccess(OAUTH_2_WEB_CLIENT_ID, /* forceRefreshToken= / false, / Additional AuthScope */ scopes) .addOnCompleteListener( task -> { if (task.isSuccessful()) { AuthResponse authresp = task.getResult(); // Send the authorization code as a string and a // list of the granted AuthScopes that were granted by the // user. Exchange for an access token. // Verify the player with Play Games Services REST APIs. } else { // Failed to retrieve authentication code. } });
Envie o token do código de autenticação OAuth ao servidor de back-end para que seja possível trocá-lo, verificar o ID do jogador nas APIs REST dos Serviços relacionados a jogos do Google Play e, por fim, autenticá-lo no jogo.
Enviar o código de autenticação do servidor
Envie o código de autenticação do servidor ao servidor de back-end para trocar por acesso e atualizar tokens. Use o token de acesso para chamar a API Play Games Services em nome do jogador e, como opção, armazene o token de atualização para receber um novo token de acesso quando ele expirar.
O snippet de código a seguir mostra como implementar o código no lado do servidor na linguagem de programação Java para trocar o código de autenticação do servidor por tokens de acesso.
Java
/** * Exchanges the authcode for an access token credential. The credential * is 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 shouldn't 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(); TokenVerifier(tokenResponse); 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; }
É possível extrair os escopos do OAuth usando as
bibliotecas de cliente de APIs do Google
em Java ou Python para receber o objeto GoogleIdTokenVerifier
. O snippet de código
abaixo mostra a implementação na linguagem de programação Java.
Java
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; /** * Gets the GoogleIdTokenVerifier object and additional OAuth scopes. * If additional OAuth scopes are not requested, the idToken will be null. * * @param tokenResponse - the tokenResponse passed from the exchangeAuthCode * function. * **/ void TokenVerifier(GoogleTokenResponse tokenResponse) { string idTokenString = tokenResponse.getIdToken(); GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory) // Specify the WEB_CLIENT_ID of the app that accesses the backend: .setAudience(Collections.singletonList(WEB_CLIENT_ID)) // Or, if multiple clients access the backend: //.setAudience(Arrays.asList(WEB_CLIENT_ID_1, WEB_CLIENT_ID_2, WEB_CLIENT_ID_3)) .build(); GoogleIdToken idToken = verifier.verify(idTokenString); // The idToken can be null if additional OAuth scopes are not requested. if (idToken != null) { Payload payload = idToken.getPayload(); // Print user identifier String userId = payload.getSubject(); System.out.println("User ID: " + userId); // Get profile information from payload String email = payload.getEmail(); boolean emailVerified = Boolean.valueOf(payload.getEmailVerified()); String name = (String) payload.get("name"); String pictureUrl = (String) payload.get("picture"); String locale = (String) payload.get("locale"); String familyName = (String) payload.get("family_name"); String givenName = (String) payload.get("given_name"); // Use or store profile information // ... } else { System.out.println("Invalid ID token."); } }
Chamar APIs REST do servidor
Consulte APIs REST para serviços do Google Play Games para ver uma descrição completa das chamadas de API disponíveis.
Veja abaixo alguns exemplos de chamadas de APIs REST que podem ser úteis:
Jogador
Quer receber o ID do jogador conectado e os dados do perfil? Chame
Players.get
com 'me'
como ID.
Amigos
Consulte o guia Amigos para mais detalhes.
Para recuperar a lista de amigos do jogador, chame Players.list com
friends_all
comocollection
.Para verificar se você tem acesso a uma lista de amigos, chame Players.get com
me
como oplayerID
e visualize o campoprofileSettings.friendsListVisibility
na resposta.
Conquistas
Consulte o guia de Conquistas para ver mais detalhes.
Para acessar uma lista das conquistas atuais, chame AchievementDefinitions.list.
Combine com uma chamada para Achievements.list para descobrir quais o jogador desbloqueou.
Chame Conquistas.unlock para desbloquear uma conquista do jogador.
Chame Conquistas.increment para informar o progresso em uma conquista e descobrir se o jogador a desbloqueou.
Se você estiver depurando um jogo que não foi para o estágio de produção, vai poder chamar Achievements.reset ou Achievements.resetAll nas APIs de gerenciamento para redefinir as conquistas ao estado original.
Placares
Consulte o guia Placares para mais detalhes.
Quer uma lista de todos os placares no jogo? Faça uma chamada para Leaderboards.list.
Se um jogador tiver terminado um jogo, envie a pontuação dele para Scores.submit e descubra se ele está entre as maiores pontuações do jogo.
Para exibir um placar, acesse os dados de Scores.list e mostre-os ao usuário.
Use Scores.listWindow para descobrir pontuações próximas à pontuação mais alta do usuário.
Para ver mais informações sobre a pontuação do jogador em um placar específico, por exemplo, se o jogador está entre os 12% dos melhores jogadores, chame Scores.get.
Se você estiver depurando um jogo, vai poder chamar Scores.reset nas APIs de gerenciamento para redefinir todas as pontuações desse jogador em um placar específico.