ตรวจสอบสิทธิ์ผู้ใช้ด้วยฟีเจอร์ลงชื่อเข้าใช้ด้วย Google

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

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

หากต้องการตั้งค่าการลงชื่อเข้าใช้ด้วย Google ให้ทำตาม 2 ขั้นตอนหลักต่อไปนี้

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

Bottom Sheet ของเครื่องมือจัดการข้อมูลเข้าสู่ระบบ
รูปที่ 1 แผ่นด้านล่างของ Credential Manager UI การเลือกข้อมูลเข้าสู่ระบบ

เพิ่มปุ่มลงชื่อเข้าใช้ด้วย Google ลงใน UI ของแอป ปุ่มลงชื่อเข้าใช้ด้วย Google ช่วยให้ผู้ใช้ลงชื่อสมัครใช้หรือลงชื่อเข้าใช้แอป Android ได้อย่างราบรื่นโดยใช้บัญชี Google ที่มีอยู่ ผู้ใช้จะคลิกปุ่มลงชื่อเข้าใช้ด้วย Google หากปิด UI ของชีตด้านล่าง หรือหากต้องการใช้ บัญชี Google ของตนเองในการลงชื่อสมัครใช้และลงชื่อเข้าใช้โดยเฉพาะ สำหรับนักพัฒนาแอป การเปลี่ยนแปลงนี้หมายถึงการเริ่มต้นใช้งานของผู้ใช้ที่ง่ายขึ้น และลดอุปสรรคระหว่างการลงชื่อสมัครใช้

ภาพเคลื่อนไหวแสดงขั้นตอนการลงชื่อเข้าใช้ด้วย Google
รูปที่ 2 UI ปุ่มลงชื่อเข้าใช้ด้วย Google ของ Credential Manager

เอกสารนี้อธิบายวิธีผสานรวมปุ่มลงชื่อเข้าใช้ด้วย Google และกล่องโต้ตอบชีตด้านล่างกับ Credential Manager API โดยใช้ไลบรารีตัวช่วย Google ID

สร้าง โปรเจ็กต์

  1. เปิดโปรเจ็กต์ใน หรือสร้างโปรเจ็กต์หากยังไม่มี
  2. ใน ตรวจสอบว่าข้อมูลทั้งหมดถูกต้องและครบถ้วน
    1. ตรวจสอบว่าแอปมีชื่อแอป โลโก้แอป และหน้าแรกของแอปที่ถูกต้อง ค่าเหล่านี้จะแสดงต่อผู้ใช้ในหน้าจอขอความยินยอมให้ใช้ฟีเจอร์ลงชื่อเข้าใช้ด้วย Google เมื่อลงชื่อสมัครใช้ และในหน้าจอแอปและบริการของบุคคลที่สาม
    2. ตรวจสอบว่าคุณได้ระบุ URL ของนโยบายความเป็นส่วนตัวและ ข้อกำหนดในการให้บริการของแอปแล้ว
  3. ใน สร้างรหัสไคลเอ็นต์ Android สำหรับแอปหากยังไม่มี คุณจะต้องระบุชื่อแพ็กเกจและลายเซ็น SHA-1 ของแอป
    1. ไปที่
    2. คลิกสร้างไคลเอ็นต์
    3. เลือกประเภทแอปพลิเคชัน Android
  4. ใน ให้สร้างรหัสไคลเอ็นต์ "เว็บแอปพลิเคชัน" ใหม่หากยังไม่ได้สร้าง คุณสามารถละเว้นช่อง "ต้นทาง JavaScript ที่ได้รับอนุญาต" และ "URI การเปลี่ยนเส้นทางที่ได้รับอนุญาต" ในตอนนี้ได้ ระบบจะใช้รหัสไคลเอ็นต์นี้เพื่อระบุเซิร์ฟเวอร์แบ็กเอนด์ เมื่อเซิร์ฟเวอร์สื่อสารกับบริการตรวจสอบสิทธิ์ของ Google
    1. ไปที่
    2. คลิกสร้างไคลเอ็นต์
    3. เลือกประเภทเว็บแอปพลิเคชัน

ประกาศทรัพยากร Dependency

ในไฟล์ build.gradle ของโมดูล ให้ประกาศทรัพยากร Dependency โดยใช้Credential Manager เวอร์ชันล่าสุด

dependencies {
  // ... other dependencies
  implementation "androidx.credentials:credentials:<latest version>"
  implementation "androidx.credentials:credentials-play-services-auth:<latest version>"
  implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>"
}

สร้างอินสแตนซ์คำขอ Google Sign-In

หากต้องการเริ่มการติดตั้งใช้งาน ให้สร้างอินสแตนซ์คำขอลงชื่อเข้าใช้ด้วย Google ใช้ GetGoogleIdOption เพื่อดึงข้อมูลโทเค็นรหัส Google ของผู้ใช้

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  // nonce string to use when generating a Google ID token
  .setNonce(nonce)
.build()

ก่อนอื่น ให้ตรวจสอบว่าผู้ใช้มีบัญชีที่เคยใช้ลงชื่อเข้าใช้แอปของคุณหรือไม่ โดยเรียกใช้ API ที่ตั้งค่าพารามิเตอร์ setFilterByAuthorizedAccounts เป็น true ผู้ใช้สามารถเลือกบัญชีที่มีอยู่เพื่อลงชื่อเข้าใช้

หากไม่มีบัญชี Google ที่ได้รับอนุญาต ผู้ใช้ควรได้รับแจ้งให้ ลงชื่อสมัครใช้ด้วยบัญชีใดก็ได้ที่มี โดยทำได้ด้วยการแจ้งให้ผู้ใช้ทราบโดย เรียกใช้ API อีกครั้งและตั้งค่า setFilterByAuthorizedAccounts เป็น false ดูข้อมูลเพิ่มเติมเกี่ยวกับการลงชื่อสมัครใช้

เปิดใช้การลงชื่อเข้าใช้โดยอัตโนมัติสำหรับผู้ใช้ที่กลับมา (แนะนำ)

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

หากต้องการเปิดใช้การลงชื่อเข้าใช้โดยอัตโนมัติ ให้ใช้ setAutoSelectEnabled(true) การลงชื่อเข้าใช้โดยอัตโนมัติ จะทำได้ก็ต่อเมื่อเป็นไปตามเกณฑ์ต่อไปนี้เท่านั้น

  • มีข้อมูลเข้าสู่ระบบรายการเดียวที่ตรงกับคำขอ ซึ่งอาจเป็นบัญชี Google หรือรหัสผ่าน และข้อมูลเข้าสู่ระบบนี้ตรงกับบัญชีเริ่มต้นในอุปกรณ์ที่ใช้ Android
  • ผู้ใช้ไม่ได้ออกจากระบบอย่างชัดเจน
  • ผู้ใช้ไม่ได้ปิดใช้การลงชื่อเข้าใช้โดยอัตโนมัติในการตั้งค่าบัญชี Google
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  // nonce string to use when generating a Google ID token
  .setNonce(nonce)
.build()

อย่าลืมจัดการการออกจากระบบอย่างถูกต้องเมื่อใช้การลงชื่อเข้าใช้โดยอัตโนมัติ เพื่อให้ผู้ใช้เลือกบัญชีที่เหมาะสมได้เสมอหลังจากที่ออกจากระบบแอปของคุณอย่างชัดเจน

ตั้งค่า Nonce เพื่อปรับปรุงความปลอดภัย

หากต้องการปรับปรุงความปลอดภัยในการลงชื่อเข้าใช้และหลีกเลี่ยงการโจมตีแบบรีเพลย์ ให้เพิ่ม setNonce เพื่อรวม Nonce ไว้ในคำขอแต่ละรายการ ดูข้อมูลเพิ่มเติม เกี่ยวกับการสร้าง Nonce

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  // nonce string to use when generating a Google ID token
  .setNonce(nonce)
.build()

สร้างขั้นตอนการลงชื่อเข้าใช้ด้วย Google

ขั้นตอนในการตั้งค่าโฟลว์การลงชื่อเข้าใช้ด้วย Google มีดังนี้

  1. สร้างอินสแตนซ์ของ GetCredentialRequest จากนั้นเพิ่ม googleIdOption ที่สร้างไว้ก่อนหน้าโดยใช้ addCredentialOption() เพื่อเรียกข้อมูลเข้าสู่ระบบ
  2. ส่งคำขอนี้ไปยังการเรียกใช้ getCredential() (Kotlin) หรือ getCredentialAsync() (Java) เพื่อดึงข้อมูลเข้าสู่ระบบที่ผู้ใช้มี
  3. เมื่อ API ทำงานสำเร็จแล้ว ให้ดึงข้อมูล CustomCredential ซึ่งมีผลลัพธ์สำหรับข้อมูล GoogleIdTokenCredential
  4. ประเภทของ CustomCredential ควรเท่ากับค่าของ GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL แปลงออบเจ็กต์ เป็น GoogleIdTokenCredential โดยใช้เมธอด GoogleIdTokenCredential.createFrom
  5. หากการแปลงสำเร็จ ให้ดึงGoogleIdTokenCredentialรหัส ตรวจสอบ และตรวจสอบสิทธิ์ข้อมูลเข้าสู่ระบบในเซิร์ฟเวอร์

  6. หาก Conversion ล้มเหลวโดยมี GoogleIdTokenParsingException แสดงว่าคุณอาจต้องอัปเดตเวอร์ชันคลัง Sign in with Google

  7. ตรวจหาประเภทข้อมูลเข้าสู่ระบบที่กำหนดเองที่ไม่รู้จัก

val request: GetCredentialRequest = GetCredentialRequest.Builder()
  .addCredentialOption(googleIdOption)
  .build()

coroutineScope {
  try {
    val result = credentialManager.getCredential(
      request = request,
      context = activityContext,
    )
    handleSignIn(result)
  } catch (e: GetCredentialException) {
    // Handle failure
  }
}
fun handleSignIn(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential
  val responseJson: String

  when (credential) {

    // Passkey credential
    is PublicKeyCredential -> {
      // Share responseJson such as a GetCredentialResponse to your server to validate and
      // authenticate
      responseJson = credential.authenticationResponseJson
    }

    // Password credential
    is PasswordCredential -> {
      // Send ID and password to your server to validate and authenticate.
      val username = credential.id
      val password = credential.password
    }

    // GoogleIdToken credential
    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract the ID to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
          // You can use the members of googleIdTokenCredential directly for UX
          // purposes, but don't use them to store or control access to user
          // data. For that you first need to validate the token:
          // pass googleIdTokenCredential.getIdToken() to the backend server.
          // see [validation instructions](https://developers.google.com/identity/gsi/web/guides/verify-google-id-token)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", e)
        }
      } else {
        // Catch any unrecognized custom 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

หากต้องการทริกเกอร์โฟลว์ปุ่มลงชื่อเข้าใช้ด้วย Google ให้ใช้ GetSignInWithGoogleOption แทน GetGoogleIdOption

val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
  serverClientId = WEB_CLIENT_ID
).setNonce(nonce)
  .build()

จัดการ GoogleIdTokenCredential ที่ส่งคืนตามที่อธิบายไว้ใน ตัวอย่างโค้ดต่อไปนี้

fun handleSignInWithGoogleOption(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 id to validate and
          // authenticate on your server.
          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 แล้ว ให้เปิดโฟลว์การตรวจสอบสิทธิ์ ในลักษณะเดียวกับที่ระบุไว้ในส่วนลงชื่อเข้าใช้ด้วย Google

เปิดใช้การลงชื่อสมัครใช้สำหรับผู้ใช้ใหม่ (แนะนํา)

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

หากไม่พบข้อมูลเข้าสู่ระบบที่บันทึกไว้ (ไม่มีบัญชี Google ที่ส่งคืนโดย getGoogleIdOption) ให้แจ้งให้ผู้ใช้ลงชื่อสมัครใช้ ก่อนอื่น ให้ตรวจสอบว่า setFilterByAuthorizedAccounts(true) มีบัญชีที่เคยใช้ก่อนหน้านี้ อยู่หรือไม่ หากไม่พบ ให้แจ้งให้ผู้ใช้ลงชื่อสมัครใช้ด้วยบัญชี Google โดยใช้ setFilterByAuthorizedAccounts(false)

ตัวอย่าง

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(WEB_CLIENT_ID)
  .build()

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

จัดการการออกจากระบบ

เมื่อผู้ใช้ลงชื่อออกจากแอป ให้เรียกใช้เมธอด clearCredentialState() API เพื่อล้างสถานะข้อมูลเข้าสู่ระบบของผู้ใช้ปัจจุบันจากผู้ให้บริการข้อมูลเข้าสู่ระบบทั้งหมด การดำเนินการนี้จะแจ้งให้ผู้ให้บริการข้อมูลเข้าสู่ระบบทั้งหมดทราบว่าควรล้างเซสชันข้อมูลเข้าสู่ระบบที่จัดเก็บไว้สำหรับ แอปที่ระบุ

ผู้ให้บริการข้อมูลเข้าสู่ระบบอาจจัดเก็บเซสชันข้อมูลเข้าสู่ระบบที่ใช้งานอยู่และใช้เซสชันดังกล่าวเพื่อ จำกัดตัวเลือกการลงชื่อเข้าใช้สำหรับการเรียก get-credential ในอนาคต เช่น อาจ จัดลำดับความสำคัญของข้อมูลเข้าสู่ระบบที่ใช้งานอยู่เหนือข้อมูลเข้าสู่ระบบอื่นๆ ที่พร้อมใช้งาน เมื่อผู้ใช้ลงชื่อออกจากแอปอย่างชัดเจน และเพื่อให้ได้รับตัวเลือกการลงชื่อเข้าใช้แบบองค์รวมในครั้งถัดไป คุณควรเรียกใช้ API นี้เพื่อให้ผู้ให้บริการล้างเซสชันข้อมูลเข้าสู่ระบบที่จัดเก็บไว้