เปิดใช้การเข้าถึงฝั่งเซิร์ฟเวอร์ในบริการเกมของ Google Play

หลังจากเลิกใช้งาน API ของ Google Sign-In แล้ว เราจะนำ SDK v1 ของเกมออกในปี 2026 หลังจากเดือนกุมภาพันธ์ 2025 คุณจะเผยแพร่ เกมที่เพิ่งผสานรวมกับ SDK v1 ของ Games ใน Google Play ไม่ได้ เราขอแนะนำให้ใช้ SDK v2 ของ Games แทน
แม้ว่าเกมที่มีอยู่ซึ่งผสานรวมกับเกมเวอร์ชัน 1 ก่อนหน้าจะยังคงทำงานได้อีก 2-3 ปี แต่เราขอแนะนำให้คุณย้ายข้อมูลไปยัง v2 ตั้งแต่เดือนมิถุนายน 2025 เป็นต้นไป
คู่มือนี้มีไว้สำหรับการใช้ SDK บริการเกมของ Play เวอร์ชัน 1 ดูข้อมูล เกี่ยวกับ SDK เวอร์ชันล่าสุดได้ที่ เอกสารประกอบ v2

หากเกมใช้เซิร์ฟเวอร์แบ็กเอนด์ เราขอแนะนำให้คุณใช้การลงชื่อเข้าใช้ด้วย Google เพื่อตรวจสอบสิทธิ์ผู้เล่นและส่งข้อมูลระบุตัวตนของผู้เล่นไปยังเซิร์ฟเวอร์แบ็กเอนด์อย่างปลอดภัย นอกจากนี้ยังช่วยให้เกมของคุณดึงข้อมูลระบุตัวตนของผู้เล่นและข้อมูลอื่นๆ ได้อย่างปลอดภัยโดยไม่ต้อง เสี่ยงต่อการถูกดัดแปลงขณะส่งผ่านอุปกรณ์

ในสถานการณ์นี้ เกมจะแจ้งให้ผู้เล่นลงชื่อเข้าใช้บริการ Google Play Games ตามปกติ เมื่อ ผู้เล่นลงชื่อเข้าใช้สำเร็จ ออบเจ็กต์ GoogleSignInAccount จะมีรหัสแบบใช้ครั้งเดียวพิเศษ (เรียกว่ารหัสการให้สิทธิ์เซิร์ฟเวอร์) ที่ไคลเอ็นต์ส่งไปยังเซิร์ฟเวอร์ จากนั้นในเซิร์ฟเวอร์ ให้แลกรหัสการให้สิทธิ์เซิร์ฟเวอร์เป็นโทเค็น OAuth 2.0 ที่เซิร์ฟเวอร์ใช้เพื่อทำการเรียกไปยัง Google Play Games Services API ได้

ดูคำแนะนำเพิ่มเติมเกี่ยวกับการเพิ่มการลงชื่อเข้าใช้ในเกมได้ที่ การลงชื่อเข้าใช้ในเกม Android

หากต้องการดูโค้ดตัวอย่างแบบละเอียดที่แสดงวิธีใช้ Google Sign-In เพื่อตรวจสอบสิทธิ์ผู้เล่น โปรดดูclientserverskeletonตัวอย่างใน GitHub

คุณต้องทำตามขั้นตอนต่อไปนี้เพื่อเข้าถึงแบบออฟไลน์

  1. ใน Google Play Console ให้สร้างข้อมูลเข้าสู่ระบบสำหรับเซิร์ฟเวอร์เกม ประเภทไคลเอ็นต์ OAuth ของข้อมูลเข้าสู่ระบบจะเป็น "เว็บ"
  2. ในแอป Android: ในขั้นตอนการลงชื่อเข้าใช้ ให้ขอรหัสการให้สิทธิ์ของเซิร์ฟเวอร์สำหรับ ข้อมูลเข้าสู่ระบบของเซิร์ฟเวอร์ แล้วส่งรหัสดังกล่าวไปยังเซิร์ฟเวอร์
  3. ในเซิร์ฟเวอร์เกม ให้แลกรหัสการให้สิทธิ์เซิร์ฟเวอร์เป็นโทเค็นการเข้าถึง OAuth โดยใช้บริการการตรวจสอบสิทธิ์ของ Google แล้วใช้โทเค็นนี้เพื่อเรียกใช้ REST API ของบริการเกมของ Play

ก่อนเริ่มต้น

ก่อนที่จะผสานรวมการลงชื่อเข้าใช้ด้วย Google เข้ากับเกม คุณจะต้องเพิ่มเกมใน Google Play Console ก่อน ตามที่อธิบายไว้ในการตั้งค่าบริการเกมของ Google Play

สร้างเว็บแอปพลิเคชันฝั่งเซิร์ฟเวอร์ที่เชื่อมโยงสำหรับเกม

บริการเกมของ Google Play ไม่รองรับ แบ็กเอนด์สำหรับเกมบนเว็บ แต่จะให้การสนับสนุนเซิร์ฟเวอร์แบ็กเอนด์ สำหรับเซิร์ฟเวอร์ของเกม Android

หากต้องการใช้ REST API สำหรับบริการเกมของ Google Play ในแอปฝั่งเซิร์ฟเวอร์ ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างเว็บแอปที่เชื่อมโยงสำหรับเกมในส่วนแอปที่ลิงก์ของ Google Play Console โปรดทราบว่า ระบบไม่ได้ใช้ launch_url สำหรับขั้นตอนการทำงานนี้ และคุณสามารถเว้นว่างไว้ได้
  2. หากต้องการดูข้อมูลเข้าสู่ระบบสำหรับแอป ให้ทำตามขั้นตอนต่อไปนี้
    1. จากเกมใน Google Play Console ให้คลิกรายละเอียดเกม
    2. เลื่อนลงไปที่ส่วนโปรเจ็กต์คอนโซล API แล้วคลิกลิงก์ ไปยังโปรเจ็กต์คอนโซล API
    3. จากหน้าจอ API และบริการ > ข้อมูลเข้าสู่ระบบใน Google API Console ให้ดาวน์โหลดไฟล์ client_secret.json สำหรับเว็บแอป และบันทึกลงในตำแหน่งที่เซิร์ฟเวอร์เข้าถึงได้ บันทึกรหัสไคลเอ็นต์ของข้อมูลเข้าสู่ระบบเพื่อใช้อ้างอิงในภายหลัง
  3. รีสตาร์ทแอปฝั่งเซิร์ฟเวอร์เพื่อให้พร้อมรับคำขอจากแอปไคลเอ็นต์ของเกม

ลงชื่อเข้าใช้ในไคลเอ็นต์

คลาส GoogleSignInClient เป็นจุดแรกเข้าหลักในการดึงข้อมูลบัญชีของผู้เล่นที่ลงชื่อเข้าใช้ในปัจจุบัน และลงชื่อเข้าใช้ผู้เล่นหากผู้เล่นยังไม่ได้ลงชื่อเข้าใช้แอปของคุณใน อุปกรณ์

หากต้องการสร้างไคลเอ็นต์การลงชื่อเข้าใช้ ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างไคลเอ็นต์การลงชื่อเข้าใช้ผ่านออบเจ็กต์ GoogleSignInOptions ใน GoogleSignInOptions.Builder เพื่อกำหนดค่าการลงชื่อเข้าใช้ คุณต้องระบุ GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
  2. นอกจากนี้ คุณยังต้องระบุว่าเกมของคุณต้องใช้รหัสการให้สิทธิ์ สำหรับเซิร์ฟเวอร์แบ็กเอนด์โดยการเรียกใช้เมธอด GoogleSignInOptions.Builder.requestServerAuthCode() ด้วยรหัสไคลเอ็นต์ของเซิร์ฟเวอร์เป็นพารามิเตอร์ คุณจะดึงรหัสการให้สิทธิ์ในภายหลังเพื่อรับโทเค็นเพื่อการเข้าถึงในเซิร์ฟเวอร์แบ็กเอนด์ตามที่อธิบายไว้ ในรับรหัสการให้สิทธิ์เซิร์ฟเวอร์
  3. เรียกใช้เมธอด GoogleSignIn.getClient() และส่งตัวเลือกที่คุณกำหนดค่าไว้ก่อนหน้านี้ หากการเรียก สำเร็จ Google Sign-In API จะแสดงอินสแตนซ์ของ GoogleSignInClient
  4. เมื่อได้รับอินสแตนซ์ GoogleSignInClient แล้ว คุณควรดำเนินการลงชื่อเข้าใช้ผู้เล่น โดยอัตโนมัติจาก onResume() ของกิจกรรมตามที่อธิบายไว้ใน การลงชื่อเข้าใช้โดยอัตโนมัติ

ตัวอย่างเช่น

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

รับรหัสการตรวจสอบสิทธิ์ของเซิร์ฟเวอร์

หากต้องการดึงรหัสการให้สิทธิ์เซิร์ฟเวอร์ที่เกมใช้สำหรับโทเค็นการเข้าถึงในเซิร์ฟเวอร์แบ็กเอนด์ได้ ให้เรียกใช้เมธอด getServerAuthCode() ในออบเจ็กต์ GoogleSignInAccount ที่ Google Sign-In แสดงเมื่อผู้เล่นลงชื่อเข้าใช้สำเร็จ

ตัวอย่างเช่น

// 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();
    }
  }
}

แลกรหัสการให้สิทธิ์ของเซิร์ฟเวอร์เป็นโทเค็นเพื่อการเข้าถึงในเซิร์ฟเวอร์

ส่งรหัสการให้สิทธิ์ของเซิร์ฟเวอร์ไปยังเซิร์ฟเวอร์แบ็กเอนด์เพื่อแลกเป็นโทเค็นเพื่อการเข้าถึงและโทเค็นการรีเฟรช ใช้โทเค็นเพื่อการเข้าถึงเพื่อเรียกใช้ Google Play Games Services API ในนามของผู้เล่น และเลือกทำดังนี้ จัดเก็บโทเค็นการรีเฟรชเพื่อรับโทเค็นเพื่อการเข้าถึงใหม่เมื่อโทเค็นเพื่อการเข้าถึงหมดอายุ

ข้อมูลโค้ดต่อไปนี้แสดงวิธีที่คุณอาจใช้โค้ดฝั่งเซิร์ฟเวอร์ในภาษาโปรแกรม Java เพื่อแลกรหัสการให้สิทธิ์ของเซิร์ฟเวอร์เป็นโทเค็นเพื่อการเข้าถึง โดยใช้แอปตัวอย่าง 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;
}

ดูข้อมูลเพิ่มเติมเกี่ยวกับการเข้าถึง Google API จากเซิร์ฟเวอร์แบ็กเอนด์ในนามของผู้เล่นที่ลงชื่อเข้าใช้ได้ที่การเปิดใช้การเข้าถึงฝั่งเซิร์ฟเวอร์

จัดการการออกจากระบบของผู้เล่น

หากต้องการออกจากระบบเกม ให้เรียกใช้เมธอด signOut() ใน GoogleSignInClient ดูข้อมูลโค้ดตัวอย่างได้ที่ การออกจากระบบของผู้เล่น

เรียกใช้ REST API จากเซิร์ฟเวอร์

โปรดดูคำอธิบายแบบเต็มของการเรียก API ที่มีได้ที่ REST API สำหรับบริการเกมของ Google Play

ตัวอย่างการเรียก REST API ที่คุณอาจเห็นว่ามีประโยชน์ ได้แก่

ผู้เล่น

  • หากต้องการรับรหัสและข้อมูลโปรไฟล์ของผู้เล่นที่ลงชื่อเข้าใช้ เรียกใช้ Players.get โดยใช้ 'me' เป็นรหัส

เพื่อน

โปรดอ่านคำแนะนำเกี่ยวกับเพื่อน ซึ่งอธิบายเกี่ยวกับฟีเจอร์เพื่อนอย่างละเอียด

  • หากต้องการดึงรายชื่อเพื่อนของผู้เล่น เรียกใช้ Players.list โดยมี 'friends_all' เป็น collection
  • คุณมีสิทธิ์เข้าถึงรายชื่อเพื่อนหรือไม่ เรียกใช้ Players.get สำหรับ me และ ดูฟิลด์ profileSettings.friendsListVisibility ในการตอบกลับ

ความสำเร็จ

โปรดอ่านคู่มือรางวัลพิเศษซึ่งอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับรางวัลพิเศษ

  • หากต้องการดูรายการรางวัลพิเศษปัจจุบัน คุณสามารถโทรหา AchievementDefinitions.list ได้
  • รวมเข้ากับการเรียกใช้ Achievements.list เพื่อดูว่าผู้เล่นปลดล็อกรางวัลใด
  • ผู้เล่นได้รับรางวัลพิเศษไหม ใช้ Achievements.unlock เพื่อปลดล็อก
  • ผู้เล่นมีความคืบหน้าในการปลดล็อกรางวัลพิเศษบางส่วนไหม ใช้ Achievements.increment เพื่อ รายงานความคืบหน้า (และดูว่าผู้เล่นปลดล็อกแล้วหรือไม่)
  • คุณกำลังแก้ไขข้อบกพร่องของเกมที่ยังไม่อยู่ในเวอร์ชันที่ใช้งานจริงใช่ไหม ลองเรียกใช้ Achievements.reset หรือ Achievements.resetAll จาก Management API เพื่อรีเซ็ตรางวัลพิเศษเป็นสถานะเดิม

ลีดเดอร์บอร์ด

โปรดอ่านคู่มือลีดเดอร์บอร์ดซึ่งอธิบายลีดเดอร์บอร์ดอย่างละเอียด

  • หากต้องการดูรายชื่อกระดานคะแนนทั้งหมดในเกม โทรหา Leaderboards.list
  • ผู้เล่นเล่นเกมจบแล้วใช่ไหม คุณสามารถส่งคะแนนไปยัง Scores.submit และดูว่า คะแนนนี้เป็นคะแนนสูงสุดใหม่หรือไม่
  • หากต้องการแสดงลีดเดอร์บอร์ด รับข้อมูลจาก Scores.list และแสดงต่อผู้ใช้
  • ใช้ Scores.listWindow เพื่อค้นหาคะแนนที่หลากหลายซึ่งใกล้เคียงกับคะแนนสูงสุดของผู้ใช้
  • หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับคะแนนของผู้เล่นในลีดเดอร์บอร์ดหนึ่งๆ (เช่น หากผู้เล่นอยู่ในกลุ่มผู้เล่น 12% แรกจากผู้เล่นทั้งหมด) ให้เรียกใช้ Scores.get
  • คุณกำลังแก้ไขข้อบกพร่องของเกมใช่ไหม ลองเรียกใช้ Scores.reset จาก Management API เพื่อรีเซ็ตคะแนนทั้งหมดของผู้เล่นรายนั้นจากลีดเดอร์บอร์ดหนึ่งๆ