เราขอแนะนำให้คุณใช้ GamesSignInClient เพื่อตรวจสอบสิทธิ์ของผู้เล่นและส่งข้อมูลประจำตัวของผู้เล่นไปยังเซิร์ฟเวอร์แบ็กเอนด์อย่างปลอดภัย ซึ่งจะช่วยให้เกมดึงข้อมูลประจำตัวและข้อมูลอื่นๆ ของผู้เล่นได้อย่างปลอดภัยโดยไม่ต้องเสี่ยงต่อการถูกแทรกแซงขณะส่งผ่านข้อมูลในอุปกรณ์
เมื่อผู้เล่นลงชื่อเข้าใช้สำเร็จแล้ว คุณสามารถขอรหัสแบบใช้ครั้งเดียวพิเศษ (เรียกว่ารหัสการให้สิทธิ์เซิร์ฟเวอร์) จาก Play Games Services v2 SDK ซึ่งไคลเอ็นต์จะส่งไปยังเซิร์ฟเวอร์ จากนั้นในเซิร์ฟเวอร์ ให้แลกเปลี่ยนรหัสการให้สิทธิ์เซิร์ฟเวอร์เพื่อรับโทเค็น OAuth 2.0 ที่เซิร์ฟเวอร์สามารถใช้เพื่อเรียกใช้ Google Play Games Services API
ดูคำแนะนำเพิ่มเติมเกี่ยวกับการเพิ่มการลงชื่อเข้าใช้ในเกมได้ที่การลงชื่อเข้าใช้สำหรับเกม Android
คุณต้องทําตามขั้นตอนต่อไปนี้เพื่อเข้าถึงแบบออฟไลน์
- ใน Google Play Console: สร้างข้อมูลเข้าสู่ระบบสำหรับเซิร์ฟเวอร์เกม ประเภทไคลเอ็นต์ OAuth ของข้อมูลเข้าสู่ระบบจะเป็น "เว็บ"
- ในแอป Android: ในการลงชื่อเข้าใช้ ให้ขอรหัสการตรวจสอบสิทธิ์เซิร์ฟเวอร์สำหรับข้อมูลเข้าสู่ระบบของเซิร์ฟเวอร์ แล้วส่งรหัสนั้นไปยังเซิร์ฟเวอร์
GamesSigninClient
สามารถขอขอบเขต OAuth 2.0 ได้ 3 รายการเมื่อขอสิทธิ์เข้าถึงฝั่งเซิร์ฟเวอร์สำหรับเว็บ API ของบริการเกมของ Play ขอบเขตที่ไม่บังคับคือEMAIL
,PROFILE
และOPEN_ID
ขอบเขตเริ่มต้น 2 รายการ ได้แก่DRIVE_APPFOLDER
และGAMES_LITE
- ในเซิร์ฟเวอร์เกม: เปลี่ยนรหัสการให้สิทธิ์เซิร์ฟเวอร์เป็นโทเค็นการเข้าถึง OAuth โดยใช้บริการการให้สิทธิ์ของ Google จากนั้นใช้โทเค็นนี้เพื่อเรียกใช้REST API ของบริการเกมของ Play
ก่อนเริ่มต้น
ก่อนอื่นคุณต้องเพิ่มเกมใน Google Play Console ตามที่อธิบายไว้ในตั้งค่าบริการเกมของ Google Play และผสานรวมฟีเจอร์ลงชื่อเข้าใช้บริการเกมของ Play กับเกม
สร้างเว็บแอปฝั่งเซิร์ฟเวอร์
บริการ Google Play Game ไม่ได้ให้การสนับสนุนแบ็กเอนด์สำหรับเกมบนเว็บ แต่ให้การสนับสนุนเซิร์ฟเวอร์แบ็กเอนด์สำหรับเซิร์ฟเวอร์เกม Android ของคุณ
หากต้องการใช้ REST API สําหรับบริการ Google Play Games ในแอปฝั่งเซิร์ฟเวอร์ ให้ทําตามขั้นตอนต่อไปนี้
- เลือกเกมใน Google Play Console
- ไปที่บริการเกมของ Play > การตั้งค่าและการจัดการ > การกำหนดค่า
- เลือกเพิ่มข้อมูลเข้าสู่ระบบเพื่อไปที่หน้าเพิ่มข้อมูลเข้าสู่ระบบ
เลือกเซิร์ฟเวอร์เกมเป็นประเภทข้อมูลเข้าสู่ระบบ แล้วไปที่ส่วนการให้สิทธิ์
- หากเซิร์ฟเวอร์เกมมีรหัสไคลเอ็นต์ OAuth อยู่แล้ว ให้เลือกรหัสจากเมนูแบบเลื่อนลง หลังจากบันทึกการเปลี่ยนแปลงแล้ว ให้ไปที่ส่วนถัดไป
- หากไม่มีรหัสไคลเอ็นต์ OAuth สำหรับเซิร์ฟเวอร์เกม คุณก็สร้างรหัสได้
- คลิกสร้างไคลเอ็นต์ OAuth แล้วคลิกลิงก์สร้างรหัสไคลเอ็นต์ OAuth
- ซึ่งจะนำคุณไปยังหน้าสร้างรหัสไคลเอ็นต์ OAuth ของ Google Cloud Platform สำหรับโปรเจ็กต์ที่เชื่อมโยงกับเกม
- กรอกแบบฟอร์มของหน้าเว็บ แล้วคลิกสร้าง อย่าลืมตั้งค่าประเภทแอปพลิเคชันเป็นเว็บแอปพลิเคชัน
- กลับไปที่ส่วนการให้สิทธิ์ของหน้าเพิ่มข้อมูลเข้าสู่ระบบ เลือกไคลเอ็นต์ OAuth ที่สร้างขึ้นใหม่ แล้วบันทึกการเปลี่ยนแปลง
รับรหัสการตรวจสอบสิทธิ์เซิร์ฟเวอร์
วิธีเรียกข้อมูลรหัสการให้สิทธิ์เซิร์ฟเวอร์ที่เกมของคุณสามารถใช้สำหรับโทเค็นการเข้าถึงในเซิร์ฟเวอร์แบ็กเอนด์
โทรหา
requestServerSideAccess
จากไคลเอ็นต์- ตรวจสอบว่าคุณใช้รหัสไคลเอ็นต์ OAuth ที่ลงทะเบียนไว้สำหรับเซิร์ฟเวอร์เกม ไม่ใช่รหัสไคลเอ็นต์ OAuth ของแอปพลิเคชัน Android
- (ไม่บังคับ) หากเซิร์ฟเวอร์เกมของคุณต้องใช้การเข้าถึงแบบออฟไลน์ (การเข้าถึงระยะยาวโดยใช้โทเค็นรีเฟรช) กับบริการ Play Games คุณสามารถตั้งค่าพารามิเตอร์
forceRefreshToken
เป็น "จริง" ได้ (ไม่บังคับ) ผู้ใช้ใหม่ควรเห็นหน้าจอขอความยินยอมเดียวสําหรับขอบเขตเพิ่มเติมเมื่อลงชื่อเข้าใช้ เมื่อยอมรับความยินยอมแล้ว คุณจะตั้งค่าพารามิเตอร์
scopes
ด้วยขอบเขต OAuthEMAIL
,PROFILE
และOPEN_ID
หากผู้ใช้ปฏิเสธความยินยอม ระบบจะส่งเฉพาะขอบเขตเริ่มต้น 2 รายการ ได้แก่DRIVE_APPFOLDER
และGAMES_LITE
ไปยังแบ็กเอนด์หน้าจอขอความยินยอมสําหรับขอบเขต OAuth เพิ่มเติม (คลิกเพื่อขยาย) GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(this); gamesSignInClient.requestServerSideAccess(OAUTH_2_WEB_CLIENT_ID, /* forceRefreshToken= / false, / Additional AuthScope */ scopes) .addOnCompleteListener( task -> { if (task.isSuccessful()) { AuthResponse authresp = task.getResult(); // Send the authorization code as a string and a // list of the granted AuthScopes that were granted by the // user. Exchange for an access token. // Verify the player with Play Games Services REST APIs. } else { // Failed to retrieve authentication code. } });
ส่งโทเค็นรหัสการให้สิทธิ์ OAuth ไปยังเซิร์ฟเวอร์แบ็กเอนด์เพื่อให้มีการแลกเปลี่ยน ยืนยันรหัสผู้เล่นกับ REST API ของบริการเกมของ Play แล้วตรวจสอบสิทธิ์กับเกม
ส่งรหัสการตรวจสอบสิทธิ์ของเซิร์ฟเวอร์
ส่งรหัสการให้สิทธิ์เซิร์ฟเวอร์ไปยังเซิร์ฟเวอร์แบ็กเอนด์เพื่อแลกโทเค็นการเข้าถึงและโทเค็นรีเฟรช ใช้โทเค็นการเข้าถึงเพื่อเรียกใช้ Play Games Services API ในนามของผู้เล่น และจัดเก็บโทเค็นรีเฟรช (ไม่บังคับ) เพื่อรับโทเค็นการเข้าถึงใหม่เมื่อโทเค็นการเข้าถึงหมดอายุ
ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้โค้ดฝั่งเซิร์ฟเวอร์ในภาษาโปรแกรม Java เพื่อแลกเปลี่ยนรหัสการตรวจสอบสิทธิ์ของเซิร์ฟเวอร์สําหรับโทเค็นการเข้าถึง
Java
/** * Exchanges the authcode for an access token credential. The credential * is 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(); TokenVerifier(tokenResponse); 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; }
คุณสามารถเรียกข้อมูลขอบเขต OAuth โดยใช้ไลบรารีของไคลเอ็นต์ Google API ใน Java หรือ Python เพื่อรับออบเจ็กต์ GoogleIdTokenVerifier
ข้อมูลโค้ดต่อไปนี้แสดงการใช้งานในภาษาโปรแกรม Java
Java
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; /** * Gets the GoogleIdTokenVerifier object and additional OAuth scopes. * If additional OAuth scopes are not requested, the idToken will be null. * * @param tokenResponse - the tokenResponse passed from the exchangeAuthCode * function. * **/ void TokenVerifier(GoogleTokenResponse tokenResponse) { string idTokenString = tokenResponse.getIdToken(); GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory) // Specify the WEB_CLIENT_ID of the app that accesses the backend: .setAudience(Collections.singletonList(WEB_CLIENT_ID)) // Or, if multiple clients access the backend: //.setAudience(Arrays.asList(WEB_CLIENT_ID_1, WEB_CLIENT_ID_2, WEB_CLIENT_ID_3)) .build(); GoogleIdToken idToken = verifier.verify(idTokenString); // The idToken can be null if additional OAuth scopes are not requested. if (idToken != null) { Payload payload = idToken.getPayload(); // Print user identifier String userId = payload.getSubject(); System.out.println("User ID: " + userId); // Get profile information from payload String email = payload.getEmail(); boolean emailVerified = Boolean.valueOf(payload.getEmailVerified()); String name = (String) payload.get("name"); String pictureUrl = (String) payload.get("picture"); String locale = (String) payload.get("locale"); String familyName = (String) payload.get("family_name"); String givenName = (String) payload.get("given_name"); // Use or store profile information // ... } else { System.out.println("Invalid ID token."); } }
เรียก REST API จากเซิร์ฟเวอร์
ดูคำอธิบายการเรียก API ทั้งหมดได้ที่ REST API สำหรับบริการ Google Play Games
ตัวอย่างการเรียก REST API ที่คุณอาจพบว่ามีประโยชน์มีดังนี้
ผู้เล่น
หากต้องการรับรหัสและข้อมูลโปรไฟล์ของผู้เล่นที่ลงชื่อเข้าใช้ เรียกใช้ Players.get โดยมี 'me'
เป็นรหัส
เพื่อน
ดูรายละเอียดได้ในคู่มือเพื่อน
หากต้องการเรียกข้อมูลรายชื่อเพื่อนของผู้เล่น ให้เรียกใช้ Players.list โดยให้
friends_all
เป็นcollection
หากต้องการยืนยันว่าคุณมีสิทธิ์เข้าถึงรายชื่อเพื่อนหรือไม่ ให้เรียกใช้ Players.get โดยให้
me
เป็นplayerID
แล้วดูช่อง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 เพื่อรีเซ็ตคะแนนทั้งหมดของผู้เล่นจากลีดเดอร์บอร์ดหนึ่งๆ