Jeśli Twoja gra korzysta z serwera backendowego, zalecamy użycie logowania w Google do uwierzytelniania graczy i przekazywania ich tożsamości na serwer backendowy w bezpieczny sposób. Dzięki temu gra może bezpiecznie pobierać dane tożsamości gracza i inne dane bez narażenia na potencjalne manipulowanie podczas przesyłania przez urządzenie.
W takim przypadku gra prosi gracza o logowanie się w Usługach Gier Google Play w zwykły sposób. Gdy gracz zaloguje się pomyślnie, obiekt GoogleSignInAccount
zawiera specjalny kod jednorazowego użytku (nazywany kodem autoryzacji serwera), który klient przekazuje serwerowi. Następnie na serwerze zastąp kod autoryzacji serwera tokenem OAuth 2.0, którego serwer może używać do wywoływania interfejsu API usług gier Google Play.
Więcej wskazówek na temat dodawania logowania w grach znajdziesz w artykule Logowanie w grach na Androida.
Szczegółowy przykład kodu pokazujący, jak używać funkcji Logowania w Google do uwierzytelniania graczy, znajdziesz w clientserverskeleton
na GitHubie.
Aby uzyskać dostęp offline, wykonaj te czynności:
- W Konsoli Google Play: utwórz dane logowania do serwera gry. Typ klienta OAuth danych uwierzytelniających to „web” (sieć).
- W aplikacji na Androida: w ramach logowania poproś o kod uwierzytelniający serwer dla danych logowania serwera i przekaż go na serwer.
- Na serwerze gry: za pomocą usług uwierzytelniania Google zastąp kod autoryzacji serwera tokenem dostępu OAuth, a potem używaj go do wywoływania interfejsów REST API usług gier Play.
Zanim zaczniesz
Zanim zintegrujesz logowanie w Google ze swoją grą, musisz najpierw dodać grę w Konsoli Google Play, zgodnie z opisem w artykule Konfigurowanie usług gier Google Play.
Tworzenie powiązanej aplikacji internetowej po stronie serwera dla gry
Usługi Google Play dotyczące gier nie zapewniają obsługi backendu gier w przeglądarce. Zapewnia jednak obsługę serwera backendu dla serwera gry na Androida.
Jeśli chcesz używać interfejsów API REST do usług Google Play Games w aplikacji po stronie serwera, wykonaj te czynności:
- Utwórz powiązaną aplikację internetową dla gry w sekcji Połączone aplikacje w Konsoli Google Play. Pamiętaj, że w tym przypadku parametr
launch_url
nie jest używany i może pozostać pusty. - Aby uzyskać informacje o danych logowania do aplikacji:
- W Konsoli Google Play kliknij Szczegóły gry.
- Przewiń w dół do sekcji Projekt w Konsoli interfejsów API i kliknij link do projektu w Konsoli interfejsów API.
- Na ekranie Interfejsy API i usługi > Dane logowania w konsoli interfejsu API Google pobierz plik
client_secret.json
swojej aplikacji internetowej i zapisz go w miejscu, do którego ma dostęp serwer. Zapisz identyfikator klienta danych logowania na później.
- Uruchom ponownie aplikację po stronie serwera, aby była gotowa do przyjmowania żądań z aplikacji klienta gry.
Logowanie się na kliencie
Klasa GoogleSignInClient
to główny punkt wejścia do pobierania danych z konta aktualnie zalogowanego gracza oraz logowania go, jeśli nie zrobił tego wcześniej w aplikacji na urządzeniu.
Aby utworzyć klienta logowania:
- Utwórz klienta logowania za pomocą obiektu
GoogleSignInOptions
. Aby skonfigurować logowanie, musisz w sekcjiGoogleSignInOptions.Builder
podać wartośćGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
. - Musisz też określić, że gra wymaga kodu uwierzytelniania dla serwera backendu. Aby to zrobić, wywołaj metodę
GoogleSignInOptions.Builder.requestServerAuthCode()
, podając jako parametr identyfikator klienta serwera. Kod autoryzacji będzie potrzebny później do tokenów dostępu na serwerze zaplecza. Aby go pobrać, wykonaj czynności opisane w sekcji Pobieranie kodu autoryzacji serwera. - Wywołaj metodę
GoogleSignIn.getClient()
i przekaż skonfigurowane wcześniej opcje. Jeśli wywołanie zakończy się powodzeniem, interfejs Google Sign-In API zwróci wystąpienie obiektuGoogleSignInClient
. - Po uzyskaniu wystąpienia
GoogleSignInClient
należy zalogować graczaonResume()
w trybie cichym z poziomu aktywności, zgodnie z opisem w artykule Logowanie cichym.
Oto przykład:
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); }
Pobieranie kodu autoryzacji serwera
Aby pobrać kod autoryzacji serwera, którego gra może używać do tokenów dostępu na serwerze backendu, wywołaj metodę getServerAuthCode()
obiektu GoogleSignInAccount
, który zwraca logowanie Google po pomyślnym zalogowaniu się gracza.
Oto przykład:
// 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(); } } }
Wymień kod uwierzytelniania serwera na token dostępu na serwerze
Wyślij kod uwierzytelniania serwera do serwera zaplecza, aby wymienić go na tokeny dostępu i odświeżania. Użyj tokena dostępu do wywołania interfejsu API Usług gier Google Play w imieniu gracza. Opcjonalnie możesz zapisać token odświeżania, aby po wygaśnięciu tokena dostępu uzyskać nowy.
Ten fragment kodu pokazuje, jak zastosować kod po stronie serwera w języku programowania Java, aby zamienić kod uwierzytelniania serwera na tokeny dostępu. Jest ona oparta na przykładowej aplikacji 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;
}
Więcej informacji o dostępie do interfejsów API Google z serwera zaplecza w imieniu zalogowanego gracza znajdziesz w artykule Włączanie dostępu po stronie serwera.
Zarządzanie wylogowywaniem
Aby wylogować graczy z gry, wywołaj metodę signOut()
w obiekcie GoogleSignInClient
. Przykładowy fragment kodu znajdziesz w sekcji Wylogowywanie użytkownika.
Wywoływanie interfejsów API REST z serwera
Pełny opis dostępnych wywołań interfejsu API znajdziesz w dokumentacji Interfejsy API REST do usług Google Play Games.
Przykłady wywołań interfejsu API REST, które mogą Ci się przydać:
Zawodnik
- Chcesz poznać identyfikator i dane profilu zalogowanego gracza? Wywołaj funkcję Players.get z identyfikatorem
'me'
.
Znajomi
Zapoznaj się z przewodnikiem na temat znajomych, który zawiera więcej informacji na ten temat.
- Chcesz pobrać listę znajomych gracza? Wywołaj Players.list z
'friends_all'
jakocollection
. - Sprawdź, czy masz dostęp do listy znajomych. W przypadku
me
wywołaj Players.get i sprawdź poleprofileSettings.friendsListVisibility
w odpowiedzi.
Osiągnięcia
Zapoznaj się z przewodnikiem dotyczącym osiągnięć, który zawiera więcej informacji o tym temacie.
- Chcesz zobaczyć listę aktualnych osiągnięć? Możesz wywołać AchievementDefinitions.list.
- Połącz to z wywołaniem Achievements.list, aby dowiedzieć się, które z nich gracz odblokował.
- Czy gracz zdobył osiągnięcie? Aby go odblokować, użyj funkcji Achievements.unlock.
- Czy gracz poczynił postępy w kierunku częściowego osiągnięcia? Użyj funkcji Achievements.increment, aby zgłosić postępy (i sprawdzić, czy gracz odblokował osiągnięcie).
- Czy debugujesz grę, która nie jest jeszcze w wersji produkcyjnej? Aby zresetować osiągnięcia do pierwotnego stanu, spróbuj wywołać Achievements.reset lub Achievements.resetAll z interfejsów API zarządzania.
Tabele wyników
Zapoznaj się z przewodnikiem po tabelach wyników, który zawiera bardziej szczegółowe informacje.
- Chcesz zobaczyć listę wszystkich tablic wyników w grze? Wywołaj funkcję Leaderboards.list.
- Czy gracz skończył już grę? Możesz przesłać ich wynik do usługi Scores.submit i sprawdzić, czy jest to nowy rekord.
- Chcesz wyświetlić tabelę wyników? Pobierz dane z pliku Scores.list i pokaż je użytkownikowi.
- Użyj kolumny Scores.listWindow, aby znaleźć asortyment wyników zbliżonych do najlepszego wyniku użytkownika.
- Aby uzyskać więcej informacji o wyniku gracza na danej tablicy wyników (np. czy należy do 12% najlepszych graczy), wywołaj funkcję Scores.get.
- Czy debugujesz grę? Spróbuj wywołać Scores.reset z interfejsu API zarządzania, aby zresetować wszystkie wyniki danego gracza na konkretnej tablicy liderów.