Nếu trò chơi của bạn sử dụng máy chủ phụ trợ, bạn nên sử dụng tính năng Đăng nhập bằng Google để xác thực người chơi và truyền danh tính của người chơi tới máy chủ phụ trợ một cách an toàn. Điều này cũng cho phép trò chơi của bạn truy xuất danh tính và các dữ liệu khác của người chơi một cách an toàn, tránh các nguy cơ bị giả mạo trong quá trình truyền qua thiết bị.
Trong trường hợp này, trò chơi của bạn sẽ nhắc người chơi đăng nhập vào Dịch vụ trò chơi của Google Play như bình thường. Khi người chơi đăng nhập thành công, đối tượng GoogleSignInAccount
sẽ chứa một mã đặc biệt chỉ sử dụng một lần (được gọi là mã xác thực máy chủ) mà ứng dụng truyền đến máy chủ. Sau đó, trên máy chủ, hãy đổi mã xác thực máy chủ để lấy mã thông báo OAuth 2.0 mà máy chủ đã dùng để thực hiện lệnh gọi tới API Dịch vụ trò chơi của Google Play.
Để được hướng dẫn thêm về cách thêm tính năng đăng nhập vào trò chơi, vui lòng xem nội dung phần Đăng nhập vào các Trò chơi trên Android.
Để xem mã mẫu chi tiết về cách sử dụng tính năng Đăng nhập bằng Google để xác thực người chơi, hãy xem mẫu clientserverskeleton
trên GitHub.
Bạn cần thực hiện các bước sau đây để truy cập ngoại tuyến:
- Trong Google Play Console: hãy tạo thông tin xác thực cho máy chủ trò chơi của bạn. Loại ứng dụng OAuth của thông tin xác thực sẽ là "web".
- Trên ứng dụng Android: trong quá trình đăng nhập, hãy yêu cầu mã xác thực máy chủ để xác thực thông tin đăng nhập của máy chủ, và truyền mã đó đến máy chủ của bạn.
- Trên máy chủ trò chơi: Hãy đổi mã xác thực máy chủ để lấy mã truy cập OAuth bằng cách sử dụng dịch vụ xác thực của Google, sau đó dùng mã này để gọi API REST trong Dịch vụ trò chơi của Play.
Trước khi bắt đầu
Trước khi có thể tích hợp tính năng Đăng nhập bằng Google vào trò chơi, trước tiên, bạn cần thêm trò chơi của mình vào Google Play Console, như mô tả trong phần Thiết lập Dịch vụ trò chơi của Google Play.
Tạo một ứng dụng web phía máy chủ được liên kết cho trò chơi
Dịch vụ trò chơi của Google Play không cung cấp chương trình hỗ trợ cho Trò chơi trên web. Tuy nhiên, hệ thống này có dịch vụ máy chủ phụ trợ cho máy chủ trò chơi Android của bạn.
Nếu bạn muốn sử dụng API REST cho Dịch vụ trò chơi của Google Play trong ứng dụng phía máy chủ, hãy làm theo các bước sau:
- Tạo một ứng dụng web được liên kết cho trò chơi của bạn trong mục Ứng dụng được liên kết của Google Play Console. Xin lưu ý rằng
launch_url
không được dùng cho luồng này và bạn có thể để trống. - Để lấy thông tin xác thực cho ứng dụng, hãy làm theo các bước sau:
- Trong trò chơi của bạn trên Google Play Console, hãy nhấp vào Chi tiết trò chơi.
- Di chuyển xuống phần Dự án Bảng điều khiển API rồi nhấp vào đường liên kết đến dự án Bảng điều khiển API.
- Trên màn hình API & Services (API và dịch vụ) > Credentials (Thông tin xác thực) trong Bảng điều khiển API của Google, hãy tải tệp
client_secret.json
xuống cho ứng dụng web của bạn rồi lưu vào vị trí mà máy chủ của bạn có thể truy cập. Ghi lại mã ứng dụng của thông tin xác thực để tham khảo sau.
- Khởi động lại ứng dụng phía máy chủ để ứng dụng này sẵn sàng chấp nhận các yêu cầu từ ứng dụng khách của trò chơi.
Thực hiện đăng nhập trên ứng dụng
Lớp GoogleSignInClient
là điểm truy cập chính để truy xuất tài khoản của người chơi hiện đã đăng nhập và để đăng nhập người chơi nếu họ chưa từng đăng nhập trên ứng dụng của bạn trong thiết bị.
Để tạo ứng dụng đăng nhập, hãy làm theo các bước sau:
- Tạo ứng dụng đăng nhập thông qua đối tượng
GoogleSignInOptions
. TrongGoogleSignInOptions.Builder
để định cấu hình tính năng đăng nhập, bạn phải chỉ địnhGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
. - Bạn cũng phải chỉ định rằng trò chơi của bạn yêu cầu mã xác thực cho máy chủ phụ trợ bằng cách gọi phương thức
GoogleSignInOptions.Builder.requestServerAuthCode()
với mã ứng dụng của máy chủ làm tham số. Bạn sẽ truy xuất mã xác thực sau này cho mã truy cập trên máy chủ phụ trợ, như mô tả trong phần Lấy mã xác thực máy chủ. - Gọi phương thức
GoogleSignIn.getClient()
và truyền vào các tuỳ chọn mà bạn đã định cấu hình trước đó. Nếu lệnh gọi thành công, API Đăng nhập bằng Google sẽ trả về một thực thể củaGoogleSignInClient
. - Sau khi lấy được thực thể
GoogleSignInClient
, bạn nên tiến hành đăng nhập người chơi một cách thầm lặng từonResume()
của hoạt động, như mô tả trong phần Thực hiện đăng nhập thầm lặng.
Ví dụ:
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); }
Lấy mã xác thực máy chủ
Để truy xuất mã xác thực máy chủ mà trò chơi của bạn có thể dùng cho mã truy cập trên máy chủ phụ trợ, hãy gọi phương thức getServerAuthCode()
trên đối tượng GoogleSignInAccount
mà tính năng Đăng nhập bằng Google trả về khi người chơi đăng nhập thành công.
Ví dụ:
// 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(); } } }
Trao đổi mã xác thực máy chủ để lấy mã truy cập trên máy chủ
Gửi mã xác thực máy chủ đến máy chủ phụ trợ để trao đổi quyền truy cập và làm mới mã thông báo. Sử dụng mã truy cập để thay mặt người chơi gọi API Dịch vụ trò chơi của Google Play, đồng thời tuỳ ý lưu trữ mã làm mới để lấy mã truy cập mới khi mã truy cập hết hạn.
Đoạn mã sau đây cho thấy cách bạn có thể triển khai mã phía máy chủ bằng ngôn ngữ lập trình Java, để trao đổi mã xác thực máy chủ lấy mã thông báo truy cập. Ứng dụng này đang sử dụng ứng dụng mẫu 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;
}
Để tìm hiểu thêm về cách truy cập API Google từ máy chủ phụ trợ thay mặt cho người chơi đã đăng nhập, hãy xem bài viết Bật quyền truy cập phía máy chủ.
Xử lý việc người chơi đăng xuất
Để đăng xuất người chơi khỏi trò chơi, hãy gọi phương thức signOut()
trên GoogleSignInClient
. Để biết đoạn mã mẫu, hãy xem phần Đăng xuất người chơi.
Thực hiện lệnh gọi API REST từ máy chủ
Hãy tham khảo API REST cho dịch vụ trò chơi của Google Play để biết nội dung mô tả đầy đủ về các lệnh gọi API hiện có.
Dưới đây là ví dụ về các lệnh gọi API REST mà bạn có thể thấy hữu ích:
Người chơi
- Bạn muốn lấy dữ liệu hồ sơ và mã nhận dạng của người chơi đã đăng nhập? Gọi Players.get với mã nhận dạng là
'me'
.
Bạn bè
Hãy nhớ xem hướng dẫn về Bạn bè để biết thêm thông tin chi tiết về tính năng này.
- Bạn muốn truy xuất danh sách bạn bè của người chơi? Gọi Players.list với
'friends_all'
làcollection
. - Kiểm tra xem bạn có quyền truy cập vào danh sách bạn bè hay không? Gọi Players.get cho
me
và xem trườngprofileSettings.friendsListVisibility
trong phản hồi.
Thành tích
Hãy nhớ xem hướng dẫn về Thành tích để biết thêm thông tin chi tiết về thành tích.
- Bạn muốn nhận danh sách các thành tích hiện tại? Bạn có thể gọi đến AchievementDefinitions.list.
- Hãy kết hợp phương thức đó với một lệnh gọi đến Achievements.list để tìm những người chơi đã mở khoá thành tích.
- Người chơi có đạt được thành tích không? Hãy sử dụng Achievements.unlock để mở khoá thành tích này!
- Người chơi có đạt được một phần thành tích không? Sử dụng Achievements.increment để báo cáo tiến trình (và tìm hiểu xem người chơi đã mở khoá thành tích hay chưa).
- Bạn đang gỡ lỗi một trò chơi chưa phát hành công khai? Hãy thử gọi phương thức Achievements.reset hoặc Achievements.resetAll từ API Quản lý để đặt lại thành tích về trạng thái ban đầu.
Bảng xếp hạng
Hãy nhớ xem hướng dẫn về Bảng xếp hạng để biết thêm thông tin chi tiết về bảng xếp hạng.
- Bạn muốn nhận danh sách tất cả các bảng điểm trong trò chơi? Thực hiện lệnh gọi đến Leaderboards.list.
- Người chơi đã chơi xong trò chơi chưa? Bạn có thể gửi điểm số của họ đến Scores.submit và tìm hiểu xem đó có phải là điểm số cao nhất mới lập hay không.
- Bạn muốn hiển thị bảng xếp hạng? Lấy dữ liệu từ Scores.list và hiển thị dữ liệu đó cho người dùng.
- Sử dụng Scores.listWindow để tìm các điểm số gần với điểm cao nhất của người dùng.
- Để biết thêm thông tin về điểm số của người chơi trong một bảng xếp hạng cụ thể (ví dụ: nếu người chơi nằm trong top 12% người chơi hàng đầu), hãy gọi Scores.get.
- Bạn đang gỡ lỗi trò chơi? Hãy thử gọi Scores.reset từ API Quản lý để đặt lại tất cả điểm số cho người chơi đó từ một bảng xếp hạng cụ thể