คู่มือนี้จะอธิบายวิธีติดตั้งใช้งานการลงชื่อเข้าใช้ด้วย Google และครอบคลุมขั้นตอนต่อไปนี้
- เพิ่มการอ้างอิงลงในแอป
- สร้างอินสแตนซ์
CredentialManager - สร้างโฟลว์ของ Bottom Sheet
- สร้างโฟลว์ของปุ่ม
- จัดการการตอบกลับการลงชื่อเข้าใช้
- จัดการข้อผิดพลาด
- จัดการการออกจากระบบ
เพิ่มการอ้างอิงไปยังแอป
ในไฟล์ build.gradle ของโมดูล ให้ประกาศทรัพยากร Dependency โดยใช้เวอร์ชันล่าสุดของ Credential Manager, Play Services Auth และ googleid
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.6.0-rc02") implementation("androidx.credentials:credentials-play-services-auth:1.6.0-rc02") implementation("com.google.android.libraries.identity.googleid:googleid:<latest version>") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.6.0-rc02" implementation "androidx.credentials:credentials-play-services-auth:1.6.0-rc02" implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>" }
สร้างอินสแตนซ์ของ Credential Manager
ใช้บริบทของแอปหรือกิจกรรมเพื่อสร้างออบเจ็กต์ CredentialManager
// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)
สร้างโฟลว์ของ Bottom Sheet
Bottom Sheet คือ UI ในตัวของเครื่องมือจัดการข้อมูลเข้าสู่ระบบ การใช้ UI นี้จะสร้างประสบการณ์การใช้งานที่สอดคล้องกันในวิธีการตรวจสอบสิทธิ์ทั้งหมด เช่น รหัสผ่าน พาสคีย์ และลงชื่อเข้าใช้ด้วย Google
กำหนดค่าคำขอลงชื่อเข้าใช้สำหรับบัญชีที่ได้รับอนุญาตก่อนหน้านี้
พยายามส่งคำขอลงชื่อเข้าใช้ Google ด้วย GetGoogleIdOption เพื่อ
เรียกข้อมูลโทเค็นรหัส Google ของผู้ใช้
ข้อมูลโค้ดต่อไปนี้จะตรวจสอบว่าบัญชีเป็นบัญชีที่ได้รับอนุญาตหรือไม่
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(true)
.setServerClientId(WEB_CLIENT_ID)
.setAutoSelectEnabled(true)
.setNonce(generateSecureRandomNonce())
.build()
กำหนดค่าออบเจ็กต์คำขอ googleIdOption ดังนี้
กรองบัญชีที่ได้รับอนุญาตก่อนหน้านี้: หากต้องการเรียกบัญชีที่ได้รับอนุญาต ซึ่งเคยใช้เพื่อลงชื่อเข้าใช้แอป ให้ตั้งค่า
setFilterByAuthorizedAccountsเป็นtrueโปรดทราบว่าค่าเริ่มต้นสำหรับ
setFilterByAuthorizedAccountsคือtrueซึ่งหมายความว่าลักษณะการทำงานเริ่มต้นสำหรับ UI ของชีตด้านล่างคือการแสดง เฉพาะบัญชีที่ได้รับอนุญาตก่อนหน้านี้ตั้งค่ารหัสไคลเอ็นต์ของเซิร์ฟเวอร์: ตั้งค่าพารามิเตอร์
setServerClientIdwebClientIdคือรหัสไคลเอ็นต์ของเว็บที่คุณตั้งค่าสำหรับ OAuth ในโปรเจ็กต์ Google Cloud ขณะทำตามข้อกำหนดเบื้องต้นเปิดใช้การลงชื่อเข้าใช้โดยอัตโนมัติ (ไม่บังคับ): หากต้องการเปิดใช้การลงชื่อเข้าใช้โดยอัตโนมัติ สำหรับผู้ใช้ที่กลับมา ให้ใช้
setAutoSelectEnabled(true)และsetFilterByAuthorizedAccounts(true)สำหรับผู้ใช้แอปของคุณ การดำเนินการนี้จะช่วยลด ความยุ่งยากที่ไม่จำเป็นหากผู้ใช้ลงชื่อเข้าใช้ไว้ก่อนหน้านี้แล้วการลงชื่อเข้าใช้โดยอัตโนมัติจะทำได้ก็ต่อเมื่อเป็นไปตามเกณฑ์ต่อไปนี้
- มีบัญชีที่ได้รับอนุญาตเพียงบัญชีเดียวในอุปกรณ์ และ บัญชีที่ได้รับอนุญาตนั้นเคยใช้ลงชื่อเข้าใช้แอปในอุปกรณ์ มาก่อน บัญชีที่ได้รับอนุญาตหลายบัญชีในอุปกรณ์จะปิดใช้การลงชื่อเข้าใช้ อัตโนมัติ
- ผู้ใช้ไม่ได้ออกจากระบบแอปอย่างชัดเจนในเซสชันก่อนหน้า
- ผู้ใช้ไม่ได้ปิดใช้การลงชื่อเข้าใช้โดยอัตโนมัติในการตั้งค่าบัญชี Google
ตั้งค่า Nonce (ไม่บังคับ): ตั้งค่า Nonce สำหรับ การยืนยันฝั่งเซิร์ฟเวอร์เพื่อเปิดใช้การรักษาความปลอดภัยที่ดียิ่งขึ้น คุณสามารถใส่ Nonce เพื่อการยืนยันฝั่งเซิร์ฟเวอร์ด้วย
setNonce()เพื่อป้องกันการโจมตีแบบเล่นซ้ำ ตรวจสอบว่าโค้ดฝั่งเซิร์ฟเวอร์ ตรวจสอบว่า Nonce ของคำขอและการตอบกลับเหมือนกันหากต้องการสร้าง Nonce ให้ใช้ฟังก์ชันที่คล้ายกับฟังก์ชันต่อไปนี้ ซึ่งจะสร้าง Nonce แบบสุ่มที่มีการเข้ารหัสที่รัดกุมตามความยาวที่ระบุ และเข้ารหัสโดยใช้
Base64
fun generateSecureRandomNonce(byteLength: Int = 32): String {
val randomBytes = ByteArray(byteLength)
SecureRandom().nextBytes(randomBytes)
return Base64.encodeToString(randomBytes, Base64.NO_WRAP or Base64.URL_SAFE or Base64.NO_PADDING)
}
ขอให้ลงชื่อเข้าใช้
ตรวจสอบว่าผู้ใช้มีบัญชีที่ได้รับอนุญาตในอุปกรณ์โดยเรียกใช้เมธอด getCredential ดังนี้
val request: GetCredentialRequest = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
coroutineScope {
try {
val result = credentialManager.getCredential(
request = request,
context = activityContext,
)
handleSignIn(result)
} catch (e: GetCredentialException) {
// Handle failures
}
}
กำหนดค่าคำขอลงชื่อเข้าใช้หากไม่มีบัญชีที่ได้รับอนุญาต
หากไม่มีผู้ใช้ที่ได้รับอนุญาตสำหรับแอปในอุปกรณ์ CredentialManager
จะแสดงผลเป็น NoCredentialException ในกรณีนี้ ให้ปิดใช้ตัวกรองบัญชีที่ได้รับอนุญาต
เพื่อให้ผู้ใช้ลงชื่อสมัครใช้ด้วยบัญชีอื่นได้
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false)
.setServerClientId(WEB_CLIENT_ID)
.setNonce(generateSecureRandomNonce())
.build()
จากนั้นขอลงชื่อเข้าใช้ในลักษณะเดียวกับที่คุณทำสำหรับบัญชีที่ได้รับอนุญาต
สร้างโฟลว์ของปุ่ม
ใช้ปุ่มหากต้องการให้ผู้ใช้ลงชื่อเข้าใช้ด้วย Google ได้ในกรณีต่อไปนี้
- ผู้ใช้ปิด UI ชีตด้านล่างของตัวจัดการข้อมูลเข้าสู่ระบบ
- ไม่มีบัญชี Google ในอุปกรณ์
- บัญชีที่มีอยู่ในอุปกรณ์ต้องมีการตรวจสอบสิทธิ์อีกครั้ง
สร้าง UI ของปุ่ม
แม้ว่าคุณจะใช้ปุ่ม Jetpack Compose ได้ แต่ก็สามารถใช้ไอคอนแบรนด์ที่ได้รับอนุมัติล่วงหน้าจากหน้าหลักเกณฑ์การสร้างแบรนด์ของฟีเจอร์ลงชื่อเข้าใช้ด้วย Google ได้
สร้างขั้นตอนการลงชื่อเข้าใช้
สร้างคำขอลงชื่อเข้าใช้ด้วย Google โดยใช้
GetSignInWithGoogleOption เพื่อดึงข้อมูลโทเค็นรหัส Google
val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
serverClientId = WEB_CLIENT_ID
).setNonce(generateSecureRandomNonce())
.build()
จากนั้นขอลงชื่อเข้าใช้ในลักษณะเดียวกับที่คุณทำสำหรับ UI แถบด้านล่าง
สร้างฟังก์ชันการลงชื่อเข้าใช้ที่แชร์สำหรับ Bottom Sheet และปุ่ม
หากต้องการจัดการการลงชื่อเข้าใช้ ให้ทำตามขั้นตอนต่อไปนี้
- ใช้ฟังก์ชัน
getCredential()ของ CredentialManager หากการตอบกลับสำเร็จ ให้ดึงข้อมูลCustomCredentialซึ่งควรมีประเภทเป็นGoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL แปลงออบเจ็กต์เป็น
GoogleIdTokenCredentialโดยใช้เมธอดGoogleIdTokenCredential.createFrom()ตรวจสอบข้อมูลเข้าสู่ระบบในเซิร์ฟเวอร์ของบริษัทอื่นที่เกี่ยวข้อง
ตรวจสอบว่าคุณจัดการข้อผิดพลาดอย่างเหมาะสม
fun handleSign(result: GetCredentialResponse) {
// Handle the successfully returned credential.
val credential = result.credential
when (credential) {
is CustomCredential -> {
if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
try {
// Use googleIdTokenCredential and extract the ID for server-side validation.
val googleIdTokenCredential = GoogleIdTokenCredential
.createFrom(credential.data)
} catch (e: GoogleIdTokenParsingException) {
Log.e(TAG, "Received an invalid google id token response", e)
}
} else {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential")
}
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential")
}
}
}
จัดการข้อผิดพลาด
ตรวจสอบข้อผิดพลาดที่ระบุไว้ในการแก้ปัญหาเพื่อให้แน่ใจว่าโค้ดของคุณจัดการ สถานการณ์ข้อผิดพลาดที่เป็นไปได้ทั้งหมด
จัดการการออกจากระบบ
คุณควรมีกลไกให้ผู้ใช้สามารถออกจากระบบแอป ตัวอย่างเช่น ผู้ใช้อาจมีบัญชี Google หลายบัญชีในอุปกรณ์และตัดสินใจ ลงชื่อเข้าใช้จากบัญชีอื่น คุณระบุข้อมูลนี้ได้ในหน้าการตั้งค่า เช่น
ผู้ให้บริการข้อมูลเข้าสู่ระบบอาจจัดเก็บเซสชันข้อมูลเข้าสู่ระบบที่ใช้งานอยู่และใช้เซสชันดังกล่าวเพื่อ จำกัดตัวเลือกการลงชื่อเข้าใช้สำหรับคำขอลงชื่อเข้าใช้ในอนาคต เช่น สามารถ จัดลำดับความสำคัญของข้อมูลเข้าสู่ระบบที่ใช้งานอยู่เหนือข้อมูลเข้าสู่ระบบอื่นๆ ที่พร้อมใช้งาน
เมื่อผู้ใช้ออกจากระบบแอป ให้เรียกใช้เมธอด clearCredentialState()
ของ API เพื่อล้างสถานะข้อมูลเข้าสู่ระบบของผู้ใช้ปัจจุบันจากผู้ให้บริการข้อมูลเข้าสู่ระบบทั้งหมด
การดำเนินการนี้จะแจ้งให้ผู้ให้บริการข้อมูลเข้าสู่ระบบทั้งหมดล้างเซสชันข้อมูลเข้าสู่ระบบที่จัดเก็บไว้สำหรับแอปที่ระบุ เพื่อให้ผู้ใช้มีตัวเลือกการลงชื่อเข้าใช้ทั้งหมดในครั้งถัดไป