หากเกมใช้เซิร์ฟเวอร์แบ็กเอนด์ เราขอแนะนำให้ใช้Google Sign-In เพื่อตรวจสอบสิทธิ์ของผู้เล่นและส่งข้อมูลประจำตัวของผู้เล่นไปยังเซิร์ฟเวอร์แบ็กเอนด์อย่างปลอดภัย นอกจากนี้ ยังช่วยให้เกมดึงข้อมูลประจำตัวและข้อมูลอื่นๆ ของผู้เล่นได้อย่างปลอดภัยโดยไม่ต้องเสี่ยงต่อการถูกแทรกแซงขณะส่งผ่านอุปกรณ์
ในกรณีนี้ เกมจะแจ้งให้ผู้เล่นลงชื่อเข้าใช้บริการ Google Play Games ตามปกติ เมื่อผู้เล่นลงชื่อเข้าใช้สำเร็จ ออบเจ็กต์ GoogleSignInAccount
จะมีรหัสพิเศษแบบใช้ครั้งเดียว (เรียกว่ารหัสการให้สิทธิ์เซิร์ฟเวอร์) ที่ไคลเอ็นต์ส่งไปยังเซิร์ฟเวอร์ จากนั้นในเซิร์ฟเวอร์ ให้แลกเปลี่ยนรหัสการให้สิทธิ์เซิร์ฟเวอร์เป็นโทเค็น OAuth 2.0 ที่เซิร์ฟเวอร์สามารถใช้เพื่อเรียกใช้ Google Play Games Services API
ดูคำแนะนำเพิ่มเติมเกี่ยวกับการเพิ่มการลงชื่อเข้าใช้ในเกมได้ที่การลงชื่อเข้าใช้ในเกม Android
หากต้องการดูตัวอย่างโค้ดโดยละเอียดที่แสดงวิธีใช้ Google Sign-In เพื่อตรวจสอบสิทธิ์ผู้เล่น โปรดดูclientserverskeleton
ตัวอย่างใน GitHub
คุณต้องทําตามขั้นตอนต่อไปนี้เพื่อเข้าถึงแบบออฟไลน์
- ใน Google Play Console: สร้างข้อมูลเข้าสู่ระบบสำหรับเซิร์ฟเวอร์เกม ประเภทไคลเอ็นต์ OAuth ของข้อมูลเข้าสู่ระบบจะเป็น "เว็บ"
- ในแอป Android: ในการลงชื่อเข้าใช้ ให้ขอรหัสการตรวจสอบสิทธิ์เซิร์ฟเวอร์สำหรับข้อมูลเข้าสู่ระบบของเซิร์ฟเวอร์ แล้วส่งรหัสดังกล่าวไปยังเซิร์ฟเวอร์
- ในเซิร์ฟเวอร์เกม: เปลี่ยนรหัสการให้สิทธิ์เซิร์ฟเวอร์เป็นโทเค็นการเข้าถึง OAuth โดยใช้บริการการให้สิทธิ์ของ Google จากนั้นใช้โทเค็นนี้เพื่อเรียกใช้ REST API ของบริการเกมของ Play
ก่อนเริ่มต้น
ก่อนผสานรวม Google Sign-In เข้ากับเกม คุณต้องเพิ่มเกมใน Google Play Console ก่อนตามที่อธิบายไว้ในการตั้งค่าบริการเกมของ Google Play
สร้างเว็บแอปพลิเคชันฝั่งเซิร์ฟเวอร์ที่เชื่อมโยงสำหรับเกม
บริการ Google Play Game ไม่ได้ให้การสนับสนุนแบ็กเอนด์สำหรับเกมบนเว็บ แต่ให้การสนับสนุนเซิร์ฟเวอร์แบ็กเอนด์สำหรับเซิร์ฟเวอร์เกม Android ของคุณ
หากต้องการใช้ REST API สําหรับบริการ Google Play Games ในแอปฝั่งเซิร์ฟเวอร์ ให้ทําตามขั้นตอนต่อไปนี้
- สร้างเว็บแอปที่เชื่อมโยงสำหรับเกมในส่วนแอปที่ลิงก์ของ Google Play Console โปรดทราบว่า
launch_url
ไม่ได้ใช้สําหรับขั้นตอนนี้และสามารถเว้นว่างไว้ได้ - หากต้องการดูข้อมูลเข้าสู่ระบบสำหรับแอป ให้ทำตามขั้นตอนต่อไปนี้
- จากเกมใน Google Play Console ให้คลิกรายละเอียดเกม
- เลื่อนลงไปที่ส่วนโปรเจ็กต์คอนโซล API แล้วคลิกลิงก์ไปยังโปรเจ็กต์คอนโซล API
- จากหน้าจอ API และบริการ > ข้อมูลเข้าสู่ระบบในคอนโซล Google API ให้ดาวน์โหลดไฟล์
client_secret.json
สำหรับเว็บแอปแล้วบันทึกไว้ในตำแหน่งที่เซิร์ฟเวอร์เข้าถึงได้ บันทึกรหัสไคลเอ็นต์ของข้อมูลเข้าสู่ระบบไว้เพื่อใช้อ้างอิงภายหลัง
- รีสตาร์ทแอปฝั่งเซิร์ฟเวอร์เพื่อให้พร้อมรับคําขอจากแอปไคลเอ็นต์ของเกม
ลงชื่อเข้าใช้ไคลเอ็นต์
คลาส GoogleSignInClient
เป็นจุดแรกเข้าหลักในการดึงข้อมูลบัญชีของผู้เล่นที่ลงชื่อเข้าใช้อยู่ในปัจจุบัน และลงชื่อเข้าใช้ผู้เล่นหากยังไม่ได้ดำเนินการดังกล่าวในแอปในอุปกรณ์
หากต้องการสร้างไคลเอ็นต์การลงชื่อเข้าใช้ ให้ทำตามขั้นตอนต่อไปนี้
- สร้างไคลเอ็นต์การลงชื่อเข้าใช้ผ่านออบเจ็กต์
GoogleSignInOptions
ในGoogleSignInOptions.Builder
คุณต้องระบุGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
เพื่อกําหนดค่าการลงชื่อเข้าใช้ - นอกจากนี้ คุณยังต้องระบุว่าเกมต้องใช้รหัสการตรวจสอบสิทธิ์สำหรับเซิร์ฟเวอร์แบ็กเอนด์ด้วย โดยเรียกใช้เมธอด
GoogleSignInOptions.Builder.requestServerAuthCode()
พร้อมรหัสไคลเอ็นต์ของเซิร์ฟเวอร์เป็นพารามิเตอร์ คุณจะเรียกดูรหัสการให้สิทธิ์ในภายหลังเพื่อรับโทเค็นการเข้าถึงบนเซิร์ฟเวอร์แบ็กเอนด์ ตามที่อธิบายไว้ในรับรหัสการให้สิทธิ์เซิร์ฟเวอร์ - เรียกใช้เมธอด
GoogleSignIn.getClient()
และส่งตัวเลือกที่คุณกําหนดค่าไว้ก่อนหน้านี้ หากการเรียกใช้สำเร็จ Google Sign-In API จะแสดงอินสแตนซ์ของGoogleSignInClient
- เมื่อได้รับอินสแตนซ์
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 Games
ตัวอย่างการเรียก 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 เพื่อรีเซ็ตคะแนนทั้งหมดของผู้เล่นจากลีดเดอร์บอร์ดหนึ่งๆ