Quyền truy cập từ phía máy chủ vào Dịch vụ trò chơi của Google Play

Bạn nên 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 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, sau khi người chơi đăng nhập thành công, bạn có thể yêu cầu loại mã đặc biệt chỉ sử dụng một lần (được gọi là mã xác thực máy chủ), từ SDK Dịch vụ trò chơi của Play phiên bản 2. mà ứng dụng truyền qua 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.

Bạn cần thực hiện các bước sau đây để truy cập ngoại tuyến:

  1. 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. Kiểu ứng dụng OAuth của thông tin xác thực sẽ là "web".
  2. 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.
  3. 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 tiên, bạn sẽ phải thêm trò chơi của mình trong Google Play Console, như mô tả ở bài viết Thiết lập Dịch vụ trò chơi của Google Play, sau đó tích hợp tính năng Đăng nhập vào Dịch vụ trò chơi của Play vào trò chơi của bạn.

Tạo một ứng dụng web phía máy chủ

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:

  1. Trong Google Play Console, hãy chọn một trò chơi.
  2. Chuyển đến mục Dịch vụ trò chơi của Play > Thiết lập và quản lý > Cấu hình.
  3. Chọn Thêm bằng chứng xác thực để chuyển đến Trang thêm thông tin xác thực. Chọn Game server (Máy chủ trò chơi) làm loại thông tin xác thực rồi tiếp tục chuyển đến mục Authorization (Uỷ quyền).
    1. Nếu máy chủ trò chơi của bạn đã có ID ứng dụng khách OAuth, hãy chọn ID này từ trình đơn thả xuống. Sau khi lưu các thay đổi, hãy chuyển sang phần tiếp theo.
    2. Nếu chưa có mã ứng dụng khách OAuth cho máy chủ trò chơi, bạn có thể tạo một mã.
      1. Nhấp vào Tạo ứng dụng khách OAuth rồi truy cập vào đường liên kết Tạo mã ứng dụng khách OAuth.
      2. Thao tác này sẽ đưa bạn đến trang Tạo mã ứng dụng khách OAuth của Google Cloud Platform cho dự án được liên kết với trò chơi.
      3. Điền vào biểu mẫu trong trang rồi nhấp vào mục tạo. Nhớ đặt Loại ứng dụng thành Ứng dụng web.
      4. Quay lại mục Authorization (Uỷ quyền) trên trang Add credential (Thông tin xác thực), chọn ứng dụng khách OAuth mới tạo và lưu thay đổi.

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 làm như sau:

  1. Gọi requestServerSideAccess từ ứng dụng.

    1. Đảm bảo rằng bạn sử dụng ID ứng dụng khách OAuth đã đăng ký cho máy chủ trò chơi, chứ không phải ID ứng dụng khách OAuth của ứng dụng Android.
    2. (Không bắt buộc) Nếu máy chủ trò chơi yêu cầu quyền truy cập ngoại tuyến (quyền truy cập dài hạn bằng cách sử dụng mã làm mới) vào Dịch vụ trò chơi của Play, thì bạn có thể đặt tham số forceRefreshToken thành true.
    GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(this);
    gamesSignInClient
      .requestServerSideAccess(OAUTH_2_WEB_CLIENT_ID, /* forceRefreshToken= */ false)
      .addOnCompleteListener( task -> {
        if (task.isSuccessful()) {
          String serverAuthToken = task.getResult();
          // Send authentication code to the backend game server to be
          // exchanged for an access token and used to verify the player
          // via the Play Games Services REST APIs.
        } else {
          // Failed to retrieve authentication code.
        }
    });
    
  2. Gửi mã thông báo xác thực OAuth cho máy chủ phụ trợ để trao đổi mã đó, xác minh mã nhận dạng Người chơi dựa trên API REST Dịch vụ trò chơi của Play, sau đó xác thực bằng trò chơi của bạn.

Gửi mã xác thực 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 để gọi API Dịch vụ trò chơi của Play thay mặt cho người chơi, đồng thời tùy ý 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ã 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. Thao tác này 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 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();

    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;
}

Thực hiện lệnh gọi API REST từ máy chủ

Vui lòng xem nội dung 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è

Xem hướng dẫn về Bạn bè để biết thêm chi tiết.

  • Để truy xuất danh sách bạn bè của người chơi, vui lòng gọi Players.list với friends_allcollection.

  • Để xác minh xem liệu bạn có quyền truy cập vào danh sách bạn bè hay không, hãy gọi phương thức Players.get với meplayerID và xem trường profileSettings.friendsListVisibility trong phản hồi.

Thành tích

Xem hướng dẫn về Thành tích để biết thêm thông tin chi tiết.

  • Để biết danh sách các thành tích hiện tại, hãy gọi phương thức 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ở khóa thành tích.

  • Hãy gọi phương thức Achievements.unlock để mở khóa thành tích của người chơi.

  • Hãy gọi phương thức Achievements.increment để báo cáo tiến độ một thành tích, đồng thời tìm hiểu xem người chơi đã mở được khóa thành tích hay chưa.

  • Nếu đang gỡ lỗi cho một trò chơi chưa được phát hành chính thức, bạn có 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

Xem hướng dẫn về Bảng xếp hạng để biết thêm thông tin chi tiết.

  • Bạn muốn nhận danh sách tất cả các bảng điểm trong trò chơi? Hãy thực hiện một lệnh gọi đến Leaderboards.list

  • Khi người chơi hoàn thành một màn chơi, bạn có thể gửi điểm số của họ đến Scores.submit, đồng thời tìm hiểu xem liệu đó có phải là điểm số cao nhất mới lập hay không.

  • Để hiển thị bảng xếp hạng, hãy lấy dữ liệu từ Scores.list và hiển thị dữ liệu đó cho người dùng.

  • Sử dụng phương thức 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ể, (chẳng hạn để biết liệu người chơi đó có nằm trong top 12% người chơi hàng đầu hay không), hãy gọi phương thức Scores.get.

  • Nếu đang gỡ lỗi cho một trò chơi, bạn có thể gọi phương thức Scores.reset có trong 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ể.