Zalecamy używanie GamesSignInClient do uwierzytelniania graczy i bezpiecznego przekazywania tożsamości gracza na serwer backendu. Dzięki temu gra może bezpiecznie pobierać tożsamość gracza i inne dane bez narażania się na potencjalne manipulacje podczas przesyłania ich przez urządzenie.
Gdy gracz przejdzie uwierzytelnianie, możesz poprosić pakiet SDK usług gier Play w wersji 2 o specjalny kod jednorazowy (zwany kodem uwierzytelniania serwera), który klient przekazuje serwerowi. Następnie na serwerze wymień kod autoryzacji serwera na token OAuth 2.0, którego serwer może używać do wywoływania interfejsu API usług gier Google Play.
Dodatkowe wskazówki dotyczące dodawania uwierzytelniania w grach znajdziesz w artykule Uwierzytelnianie na platformie w przypadku gier na Androida.
Aby uzyskać dostęp offline, wykonaj te czynności:
- W Konsoli Google Play: utwórz dane logowania dla serwera gry. Typ klienta OAuth danych logowania będzie miał wartość „web”.
- W aplikacji na Androida: w ramach uwierzytelniania platformy poproś o kod uwierzytelniania serwera dla danych logowania serwera i przekaż go na serwer. Aplikacja
GamesSigninClient
może prosić o 3 zakresy OAuth 2.0, gdy żąda dostępu po stronie serwera do interfejsów API usług internetowych Google Play Games. Opcjonalne zakresy toEMAIL
,PROFILE
iOPEN_ID
. Domyślne zakresy toDRIVE_APPFOLDER
iGAMES_LITE
. - Na serwerze gry: wymień kod autoryzacji serwera na token dostępu OAuth za pomocą usług uwierzytelniania Google, a następnie użyj go do wywoływania interfejsów REST API usług gier Play.
Zanim zaczniesz
Najpierw musisz dodać grę w Konsoli Google Play, zgodnie z opisem w artykule Konfigurowanie usług gier Google Play, i zintegrować z nią uwierzytelnianie na platformie Usługi gier Play.
Tworzenie aplikacji internetowej po stronie serwera
Usługi gier Google Play nie zapewniają obsługi backendu w przypadku gier internetowych. Zapewnia jednak obsługę serwera backendu serwera gry na Androida.
Jeśli chcesz używać interfejsów API REST do usług gier Play w aplikacji po stronie serwera, wykonaj te czynności:
- W Konsoli Google Play wybierz grę.
- Kliknij Usługi gier Play > Konfiguracja i zarządzanie > Konfiguracja.
- Kliknij Dodaj dane logowania, aby przejść na stronę Dodaj dane logowania.
Jako typ danych logowania wybierz Serwer gier i przejdź do sekcji Autoryzacja.
- Jeśli Twój serwer gier ma już identyfikator klienta OAuth, wybierz go z menu. Po zapisaniu zmian przejdź do następnej sekcji.
- Jeśli nie masz jeszcze identyfikatora klienta OAuth na potrzeby serwera gry, możesz go utworzyć.
- Kliknij Utwórz klienta OAuth i skorzystaj z linku Utwórz identyfikator klienta OAuth.
- Spowoduje to przejście do strony Tworzenie identyfikatora klienta OAuth w Google Cloud Platform dla projektu powiązanego z Twoją grą.
- Wypełnij formularz na stronie i kliknij Utwórz. Ustaw typ aplikacji na Aplikacja internetowa.
- Wróć do sekcji Autoryzacja na stronie Dodaj dane logowania, wybierz nowo utworzonego klienta OAuth i zapisz zmiany.
Pobieranie kodu autoryzacji serwera
Aby pobrać kod autoryzacji serwera, którego gra może używać do uzyskiwania tokenów dostępu na serwerze backendu:
- Zadzwoń do
requestServerSideAccess
z klienta.- Upewnij się, że używasz identyfikatora klienta OAuth zarejestrowanego na serwerze gry, a nie identyfikatora klienta OAuth aplikacji na Androida.
- (Opcjonalnie) Jeśli serwer gry wymaga dostępu offline (długotrwałego dostępu za pomocą tokena odświeżania) do Usług gier Play, możesz ustawić parametr
forceRefreshToken
na wartość true.
(Opcjonalnie) W ramach uwierzytelniania nowi użytkownicy powinni zobaczyć jeden ekran zgody na dodatkowe zakresy. Po uzyskaniu zgody użytkownika ustaw parametr
scopes
z zakresami OAuthEMAIL
,PROFILE
iOPEN_ID
. Jeśli użytkownicy nie wyrażą zgody, do backendu zostaną wysłane tylko 2 domyślne zakresy:DRIVE_APPFOLDER
iGAMES_LITE
.Ekran zgody na dodatkowe zakresy OAuth. (kliknij, aby powiększyć). 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. } });
Wyślij token kodu autoryzacji OAuth na serwer backendu, aby można go było wymienić, zweryfikować identyfikator gracza za pomocą interfejsów REST API usług gier Play, a następnie uwierzytelnić w grze.
Przesyłanie kodu autoryzacji serwera
Wyślij kod autoryzacji serwera na serwer backendu, aby wymienić go na tokeny dostępu i odświeżania. Użyj tokena dostępu, aby wywołać interfejs Play Games Services API w imieniu gracza. Opcjonalnie możesz też zapisać token odświeżania, aby uzyskać nowy token dostępu, gdy ten wygaśnie.
Więcej informacji o działaniu identyfikatorów graczy znajdziesz w artykule Identyfikatory graczy nowej generacji.
Poniższy fragment kodu pokazuje, jak możesz zaimplementować kod po stronie serwera w języku programowania Java, aby wymienić kod autoryzacji serwera na tokeny dostępu.
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; }
Zakresy OAuth możesz pobrać za pomocą bibliotek klienta interfejsu API Google w językach Java lub Python, aby uzyskać obiekt GoogleIdTokenVerifier
. Poniższy fragment kodu
pokazuje implementację w języku programowania 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."); } }
Wywoływanie interfejsów API REST z serwera
Pełny opis dostępnych wywołań interfejsu API znajdziesz w artykule Interfejsy REST API usług gier Google Play.
Przykłady wywołań interfejsu API REST, które mogą być przydatne:
Zawodnik
Chcesz uzyskać uwierzytelniony identyfikator gracza i dane profilu? Wywołaj funkcję Players.get z parametrem 'me'
jako identyfikatorem.
Znajomi
Szczegółowe informacje znajdziesz w przewodniku Znajomi.
Aby pobrać listę znajomych gracza, wywołaj funkcję Players.list, używając
friends_all
jakocollection
.Aby sprawdzić, czy masz dostęp do listy znajomych, wywołaj funkcję Players.get z parametrem
me
jakoplayerID
i sprawdź poleprofileSettings.friendsListVisibility
w odpowiedzi.
Osiągnięcia
Szczegółowe informacje znajdziesz w przewodniku po osiągnięciach.
Aby uzyskać listę bieżących osiągnięć, wywołaj funkcję AchievementDefinitions.list.
Połącz to z wywołaniem funkcji Achievements.list, aby sprawdzić, które osiągnięcia zostały odblokowane przez gracza.
Wywołaj funkcję Achievements.unlock, aby odblokować osiągnięcie gracza.
Wywołaj funkcję Achievements.increment aby zgłosić postępy w zdobywaniu osiągnięcia i sprawdzić, czy gracz je odblokował.
Jeśli debugujesz grę, która nie została jeszcze udostępniona w wersji produkcyjnej, możesz wywołać funkcje Achievements.reset lub Achievements.resetAll z interfejsów Management API, aby zresetować osiągnięcia do pierwotnego stanu.
Tabele wyników
Szczegółowe informacje znajdziesz w przewodniku po tablicach wyników.
Aby uzyskać listę wszystkich tablic wyników w grze, wywołaj funkcję Leaderboards.list.
Gdy gracz skończy grę, możesz przesłać jego wynik do funkcji Scores.submit i sprawdzić, czy jest to nowy rekord.
Aby wyświetlić tabelę wyników, pobierz dane z Scores.list i pokaż je użytkownikowi.
Użyj metody Scores.listWindow, aby znaleźć różne wyniki zbliżone do najlepszego wyniku użytkownika.
Aby uzyskać więcej informacji o wyniku gracza w danej tabeli wyników (np. czy gracz znajduje się w 12% najlepszych graczy), wywołaj Scores.get.
Jeśli debugujesz grę, możesz wywołać metodę Scores.reset z interfejsów Management API, aby zresetować wszystkie wyniki danego gracza w konkretnej tabeli wyników.