การลงชื่อเข้าใช้บัญชีที่ลิงก์ช่วยให้ผู้ใช้ลงชื่อเข้าใช้ด้วย Google ด้วย One Tap ได้ ที่ลิงก์กับบัญชี Google ของตนกับบริการของคุณอยู่แล้ว ซึ่งช่วยปรับปรุง สำหรับผู้ใช้มากขึ้นเพราะสามารถลงชื่อเข้าใช้ได้ในคลิกเดียว โดยไม่ต้องลงชื่อเข้าใช้ใหม่ ชื่อผู้ใช้และรหัสผ่าน และยังช่วยลดโอกาสที่ผู้ใช้จะสร้าง บัญชีที่ซ้ำกันในบริการของคุณ
การลงชื่อเข้าใช้บัญชีที่ลิงก์พร้อมใช้งานโดยเป็นส่วนหนึ่งของขั้นตอนการลงชื่อเข้าใช้ด้วย One Tap สำหรับ Android ซึ่งหมายความว่าคุณไม่ต้องนำเข้าคลังแยกต่างหากหากแอป เปิดใช้ฟีเจอร์ One Tap เรียบร้อยแล้ว
ในเอกสารนี้ คุณจะได้เรียนรู้วิธีแก้ไขแอป Android เพื่อให้รองรับ การลงชื่อเข้าใช้บัญชีที่ลิงก์
วิธีการทำงาน
- คุณเลือกแสดงบัญชีที่ลิงก์ได้ในระหว่างขั้นตอนการลงชื่อเข้าใช้ด้วย One Tap
- หากผู้ใช้ลงชื่อเข้าใช้ Google และได้ลิงก์บัญชี Google กับ บัญชีของลูกค้าในบริการของคุณ ระบบจะแสดงผลโทเค็นรหัสสำหรับบัญชีที่ลิงก์ไว้ ของคุณได้
- ผู้ใช้จะเห็นข้อความแจ้งให้ลงชื่อเข้าใช้ด้วย One Tap พร้อมตัวเลือกให้ลงชื่อเข้าใช้บริการด้วยบัญชีที่ลิงก์
- หากผู้ใช้เลือกที่จะใช้บัญชีที่ลิงก์ต่อ ระบบจะส่งโทเค็นระบุตัวตนของผู้ใช้กลับไปยังแอปของคุณ คุณสามารถจับคู่โทเค็นนี้กับโทเค็นที่ส่งไปยังเซิร์ฟเวอร์ในขั้นตอนที่ 2 เพื่อระบุผู้ใช้ที่เข้าสู่ระบบ
ตั้งค่า
ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์
รับบริการ Google Play เวอร์ชันล่าสุดในโฮสต์การพัฒนาโดยทำดังนี้
ในส่วนเครื่องมือ SDK ให้ค้นหาบริการ Google Play
หากสถานะสำหรับแพ็กเกจเหล่านี้คือ "ไม่ได้ติดตั้ง" ให้เลือกทั้ง 2 แพ็กเกจแล้วคลิก ติดตั้งแพ็กเกจ
กำหนดค่าแอป
ในไฟล์
build.gradle
ระดับโปรเจ็กต์ ให้ใส่ที่เก็บ Maven ของ Google ทั้งในส่วนbuildscript
และallprojects
buildscript { repositories { google() } } allprojects { repositories { google() } }
เพิ่มทรัพยากร Dependency สำหรับ API "ลิงก์กับ Google" ลงในไฟล์ Gradle ระดับแอปของโมดูล ซึ่งโดยปกติจะเป็น
app/build.gradle
dependencies { implementation 'com.google.android.gms:play-services-auth:21.2.0' }
แก้ไขแอป Android เพื่อรองรับการลงชื่อเข้าใช้บัญชีที่ลิงก์
ในตอนท้ายของขั้นตอนการลงชื่อเข้าใช้บัญชีที่ลิงก์ โทเค็นรหัสจะส่งกลับไปยัง แอป ยืนยันความสมบูรณ์ของโทเค็นรหัสก่อนให้ผู้ใช้ลงชื่อเข้าใช้
ตัวอย่างโค้ดต่อไปนี้แสดงรายละเอียดขั้นตอนในการดึงข้อมูล ยืนยันโทเค็นรหัส และหลังจากนั้น ให้ผู้ใช้ลงชื่อเข้าใช้
สร้างกิจกรรมเพื่อรับผลลัพธ์ของ Intent การลงชื่อเข้าใช้
Kotlin
private val activityResultLauncher = registerForActivityResult( ActivityResultContracts.StartIntentSenderForResult()) { result -> if (result.resultCode == RESULT_OK) { try { val signInCredentials = Identity.signInClient(this) .signInCredentialFromIntent(result.data) // Review the Verify the integrity of the ID token section for // details on how to verify the ID token verifyIdToken(signInCredential.googleIdToken) } catch (e: ApiException) { Log.e(TAG, "Sign-in failed with error code:", e) } } else { Log.e(TAG, "Sign-in failed") } }
Java
private final ActivityResultLauncher<IntentSenderResult> activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), result -> { If (result.getResultCode() == RESULT_OK) { try { SignInCredential signInCredential = Identity.getSignInClient(this) .getSignInCredentialFromIntent(result.getData()); verifyIdToken(signInCredential.getGoogleIdToken()); } catch (e: ApiException ) { Log.e(TAG, "Sign-in failed with error:", e) } } else { Log.e(TAG, "Sign-in failed") } });
สร้างคำขอลงชื่อเข้าใช้
Kotlin
private val tokenRequestOptions = GoogleIdTokenRequestOptions.Builder() .supported(true) // Your server's client ID, not your Android client ID. .serverClientId(getString("your-server-client-id") .filterByAuthorizedAccounts(true) .associateLinkedAccounts("service-id-of-and-defined-by-developer", scopes) .build()
Java
private final GoogleIdTokenRequestOptions tokenRequestOptions = GoogleIdTokenRequestOptions.Builder() .setSupported(true) .setServerClientId("your-service-client-id") .setFilterByAuthorizedAccounts(true) .associateLinkedAccounts("service-id-of-and-defined-by-developer", scopes) .build()
เปิด Intent ที่รอการลงชื่อเข้าใช้
Kotlin
Identity.signInClient(this) .beginSignIn( BeginSignInRequest.Builder() .googleIdTokenRequestOptions(tokenRequestOptions) .build()) .addOnSuccessListener{result -> activityResultLauncher.launch(result.pendingIntent.intentSender) } .addOnFailureListener {e -> Log.e(TAG, "Sign-in failed because:", e) }
Java
Identity.getSignInClient(this) .beginSignIn( BeginSignInRequest.Builder() .setGoogleIdTokenRequestOptions(tokenRequestOptions) .build()) .addOnSuccessListener(result -> { activityResultLauncher.launch( result.getPendingIntent().getIntentSender()); }) .addOnFailureListener(e -> { Log.e(TAG, "Sign-in failed because:", e); });
ยืนยันความสมบูรณ์ของโทเค็นรหัส
ในการยืนยันว่าโทเค็นถูกต้อง ให้ตรวจสอบสิ่งต่อไปนี้ เป็นไปตามเกณฑ์ต่อไปนี้
- Google ลงชื่อโทเค็นรหัสอย่างถูกต้อง ใช้คีย์สาธารณะของ Google
(มีให้บริการใน
JWK หรือ
PEM)
เพื่อยืนยันลายเซ็นของโทเค็น คีย์เหล่านี้จะมีการหมุนเวียนเป็นประจำ ตรวจสอบ
ส่วนหัว
Cache-Control
ในการตอบกลับเพื่อกำหนดเวลาที่ คุณควรดึงข้อมูลอีกครั้ง - ค่า
aud
ในโทเค็นรหัสเท่ากับหนึ่งในแอปของคุณ Client-ID การตรวจสอบนี้จำเป็นต่อการป้องกันโทเค็นรหัสที่ออกให้กับเครื่องมือที่เป็นอันตราย ที่ใช้เข้าถึงข้อมูลเกี่ยวกับผู้ใช้รายเดียวกันในเซิร์ฟเวอร์แบ็กเอนด์ของแอป - ค่าของ
iss
ในโทเค็นรหัสเท่ากับaccounts.google.com
หรือhttps://accounts.google.com
- โทเค็นรหัสยังไม่เลยเวลาหมดอายุ (
exp
) - หากต้องการตรวจสอบว่าโทเค็นรหัสแสดงถึง Google Workspace หรือ Cloud
บัญชีขององค์กร คุณสามารถตรวจสอบการอ้างสิทธิ์
hd
ซึ่งระบุการอ้างสิทธิ์ที่โฮสต์ไว้ โดเมนของผู้ใช้ ต้องใช้เมื่อจำกัดการเข้าถึงทรัพยากรไว้สำหรับสมาชิกของ บางโดเมน การที่ไม่มีการอ้างสิทธิ์นี้แสดงว่าบัญชีไม่ได้เป็นของ โดเมนที่ Google โฮสต์
เมื่อใช้ช่อง email
, email_verified
และ hd
คุณจะระบุได้ว่า
Google โฮสต์และมีสิทธิ์สำหรับอีเมล ในกรณีที่ Google เชื่อถือได้
ผู้ใช้ดังกล่าวเป็นเจ้าของบัญชีที่ถูกต้อง และคุณสามารถข้ามรหัสผ่าน หรือ
มากขึ้นอย่างไร
กรณีที่ Google เชื่อถือได้
email
มีส่วนต่อท้าย@gmail.com
นี่คือบัญชี Gmailemail_verified
เป็นจริงและตั้งค่าhd
แล้ว นี่คือบัญชี G Suite
ผู้ใช้อาจลงทะเบียนบัญชี Google โดยไม่ใช้ Gmail หรือ G Suite ได้ วันและเวลา
email
ไม่มีคำต่อท้าย @gmail.com
และ hd
ไม่มี Google ไม่มี
แนะนำให้ใช้รหัสผ่านหรือวิธีการอื่นๆ ในการพิสูจน์ยืนยัน
ผู้ใช้รายนั้น email_verified
ก็อาจเป็นจริงได้ เนื่องจาก Google ได้ยืนยัน
ผู้ใช้เมื่อมีการสร้างบัญชี Google แต่การเป็นเจ้าของของบุคคลที่สาม
บัญชีอีเมลของคุณอาจมีการเปลี่ยนแปลง
แทนที่จะเขียนโค้ดของคุณเองเพื่อดำเนินการตามขั้นตอนการยืนยันเหล่านี้ เราขอแนะนำอย่างยิ่ง
ขอแนะนำให้ใช้ไลบรารีไคลเอ็นต์ Google API สำหรับแพลตฟอร์มของคุณ หรือใช้งานทั่วไป
ไลบรารี JWT สำหรับการพัฒนาและการแก้ไขข้อบกพร่อง คุณสามารถโทรหา tokeninfo
ปลายทางการตรวจสอบ
ใช้ไลบรารีของไคลเอ็นต์ Google API
การใช้ ไลบรารีไคลเอ็นต์ Java Google API เป็นวิธีที่แนะนำในการตรวจสอบโทเค็น Google ID ในสภาพแวดล้อมการใช้งานจริง
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;
...
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
// Specify the CLIENT_ID of the app that accesses the backend:
.setAudience(Collections.singletonList(CLIENT_ID))
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
// (Receive idTokenString by HTTPS POST)
GoogleIdToken idToken = verifier.verify(idTokenString);
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.");
}
เมธอด GoogleIdTokenVerifier.verify()
จะยืนยันลายเซ็น JWT
การอ้างสิทธิ์ aud
, การอ้างสิทธิ์ iss
และการอ้างสิทธิ์เหล่านั้นexp
หากต้องการตรวจสอบว่าโทเค็นรหัสแสดงถึง Google Workspace หรือ Cloud
บัญชีขององค์กร คุณสามารถยืนยันการอ้างสิทธิ์ hd
โดยการตรวจสอบชื่อโดเมน
แสดงผลโดยเมธอด Payload.getHostedDomain()
การเรียกใช้ปลายทางTokeninfo
วิธีง่ายๆ ในการตรวจสอบลายเซ็นโทเค็นรหัสเพื่อแก้ไขข้อบกพร่องคือ
ใช้ปลายทาง tokeninfo
การเรียกใช้ปลายทางนี้ต้องใช้
คำขอเครือข่ายเพิ่มเติมซึ่งทำหน้าที่ตรวจสอบส่วนใหญ่ให้คุณในขณะที่คุณทดสอบ
การตรวจสอบความถูกต้องและการแยกเพย์โหลดในโค้ดของคุณเอง ไม่เหมาะกับการใช้งานจริง
รหัสเพราะคำขออาจถูกควบคุมหรือมีข้อผิดพลาดเป็นระยะๆ
หากต้องการตรวจสอบโทเค็นรหัสโดยใช้ปลายทาง tokeninfo
ให้สร้าง HTTPS
คำขอ POST หรือ GET ไปยังปลายทาง แล้วส่งโทเค็นรหัสใน
พารามิเตอร์ id_token
เช่น หากต้องการตรวจสอบโทเค็น "XYZ123" ให้ส่งคำขอ GET ต่อไปนี้
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
หากโทเค็นมีการรับรองอย่างถูกต้อง และ iss
และ exp
จะมีค่าที่คาดไว้ คุณจะได้รับการตอบสนอง HTTP 200 โดยที่ส่วนเนื้อหา
มีการอ้างสิทธิ์โทเค็นรหัสในรูปแบบ JSON
ตัวอย่างคำตอบมีดังนี้
{ // These six fields are included in all Google ID Tokens. "iss": "https://accounts.google.com", "sub": "110169484474386276334", "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "iat": "1433978353", "exp": "1433981953", // These seven fields are only included when the user has granted the "profile" and // "email" OAuth scopes to the application. "email": "testuser@gmail.com", "email_verified": "true", "name" : "Test User", "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg", "given_name": "Test", "family_name": "User", "locale": "en" }
หากต้องการตรวจสอบว่าโทเค็นรหัสแสดงถึงบัญชี Google Workspace ให้ตรวจสอบ
การอ้างสิทธิ์ hd
ซึ่งระบุโดเมนที่โฮสต์ของผู้ใช้ ต้องใช้เมื่อ
การจำกัดการเข้าถึงทรัพยากรไว้เฉพาะสมาชิกของบางโดเมนเท่านั้น การไม่มีการอ้างสิทธิ์นี้
ระบุว่าบัญชีไม่ได้เป็นของโดเมนที่โฮสต์ของ Google Workspace