Login Akun Tertaut untuk Android

Login Akun Tertaut memungkinkan Login Sekali Ketuk dengan Google untuk pengguna yang telah menautkan Akun Google mereka ke layanan Anda. Hal ini meningkatkan bagi pengguna karena mereka dapat login dengan sekali klik, tanpa perlu memasukkan nama pengguna dan {i>password<i} mereka. Hal ini juga mengurangi kemungkinan pengguna membuat akun duplikat di layanan Anda.

Login dengan Akun Tertaut tersedia sebagai bagian dari alur Login Sekali Ketuk untuk Android. Ini berarti Anda tidak perlu mengimpor library terpisah jika aplikasi sudah mengaktifkan fitur Sekali Ketuk.

Dalam dokumen ini, Anda akan mempelajari cara memodifikasi aplikasi Android untuk mendukung Login Akun Tertaut.

Cara kerjanya

  1. Anda memilih untuk menampilkan akun tertaut selama alur Login Sekali Ketuk.
  2. Jika pengguna login di Google dan telah menautkan Akun Google-nya dengan akun mereka di layanan Anda, token ID akan dikembalikan untuk menggunakan akun layanan.
  3. Pengguna akan melihat perintah login Sekali Ketuk dengan opsi untuk login ke dengan akun tertaut mereka.
  4. Jika pengguna memilih untuk melanjutkan dengan akun tertaut, token ID pengguna akan ditampilkan ke aplikasi Anda. Anda mencocokkan token ini dengan token yang dikirim ke server Anda pada langkah 2 untuk mengidentifikasi pengguna yang login.

Penyiapan

Menyiapkan lingkungan pengembangan

Dapatkan layanan Google Play terbaru di host pengembangan Anda:

  1. Buka Android SDK Manager.
  1. Di bagian SDK Tools, temukan layanan Google Play.

  2. Jika status untuk paket ini belum Terinstal, pilih keduanya dan klik Instal Paket.

Mengonfigurasi aplikasi Anda

  1. Di file build.gradle level project, sertakan repositori Maven Google di bagian buildscript dan allprojects.

    buildscript {
        repositories {
            google()
        }
    }
    
    allprojects {
        repositories {
            google()
        }
    }
    
  2. Tambahkan dependensi untuk "Link with Google" ke antarmuka modul gradle level aplikasi, yang biasanya adalah app/build.gradle:

    dependencies {
      implementation 'com.google.android.gms:play-services-auth:21.2.0'
    }
    

Memodifikasi aplikasi Android untuk mendukung Login dengan Akun Tertaut

Di akhir alur Login Akun Tertaut, token ID akan ditampilkan ke aplikasi Anda. Integritas token ID harus diverifikasi sebelum membuat pengguna login.

Contoh kode berikut menjelaskan langkah-langkah untuk mengambil, memverifikasi token ID, dan kemudian membuat pengguna login.

  1. Membuat aktivitas untuk menerima hasil intent Login

    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")
        }
    });
    
  2. Membuat permintaan login

    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()
    
  3. Meluncurkan intent Tertunda Login

    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);
    });
    

Memverifikasi integritas token ID

Untuk memverifikasi bahwa token valid, pastikan hal berikut kriteria terpenuhi:

  • Token ID ditandatangani dengan benar oleh Google. Gunakan kunci publik Google (tersedia di JWK atau format PEM) untuk memverifikasi tanda tangan token. Kunci-kunci ini dirotasi secara berkala; memeriksa header Cache-Control dalam respons untuk menentukan kapan Anda harus mengambilnya lagi.
  • Nilai aud di token ID sama dengan salah satu nilai aplikasi Anda client ID. Pemeriksaan ini diperlukan untuk mencegah token ID yang dikeluarkan untuk aplikasi yang digunakan untuk mengakses data tentang pengguna yang sama di server backend aplikasi Anda.
  • Nilai iss di token ID sama dengan accounts.google.com atau https://accounts.google.com.
  • Waktu habis masa berlaku (exp) token ID belum berlalu.
  • Jika Anda perlu memvalidasi bahwa token ID tersebut mewakili jaringan Google Workspace atau Cloud akun organisasi Anda, Anda dapat memeriksa klaim hd, yang menunjukkan bahwa domain pengguna. Ini harus digunakan ketika membatasi akses ke sumber daya hanya untuk anggota domain tertentu. Tidak adanya klaim ini mengindikasikan bahwa akun tersebut bukan milik Domain yang dihosting Google.

Dengan kolom email, email_verified, dan hd, Anda dapat menentukan apakah Google menghosting dan bersifat otoritatif untuk alamat email. Dalam kasus di mana Google bersifat otoritatif, pengguna diketahui sebagai pemilik akun yang sah, dan Anda dapat melewati {i>password<i} atau metode-metode tantangan.

Kasus saat Google bersifat otoritatif:

  • email memiliki akhiran @gmail.com, ini adalah akun Gmail.
  • email_verified benar dan hd ditetapkan, ini adalah akun G Suite.

Pengguna dapat mendaftar ke Akun Google tanpa menggunakan Gmail atau G Suite. Kapan email tidak berisi akhiran @gmail.com dan hd tidak ada, Google tidak otoritatif, dan menggunakan {i>password<i} atau metode verifikasi lainnya disarankan untuk pengguna. email_verified juga bisa benar karena Google awalnya memverifikasi pengguna saat Akun Google dibuat, namun kepemilikan pihak ketiga akun email Anda mungkin telah berubah.

Daripada menulis kode Anda sendiri untuk melakukan langkah verifikasi ini, kami sangat merekomendasikan penggunaan library klien Google API untuk platform Anda, atau library JWT. Untuk pengembangan dan proses debug, Anda dapat memanggil tokeninfo endpoint validasi.

Menggunakan Library Klien Google API

Menggunakan Library Klien Google API Java adalah cara yang direkomendasikan untuk memvalidasi token ID Google di lingkungan produksi.

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.");
  }

Metode GoogleIdTokenVerifier.verify() memverifikasi tanda tangan JWT, klaim aud, klaim iss, dan klaim exp.

Jika Anda perlu memvalidasi bahwa token ID tersebut mewakili jaringan Google Workspace atau Cloud akun organisasi, Anda dapat memverifikasi klaim hd dengan memeriksa nama domain yang ditampilkan oleh metode Payload.getHostedDomain().

Memanggil endpoint tokeninfo

Cara mudah untuk memvalidasi tanda tangan token ID untuk proses debug adalah dengan gunakan endpoint tokeninfo. Memanggil endpoint ini melibatkan permintaan jaringan tambahan yang melakukan sebagian besar validasi untuk Anda saat menguji validasi dan ekstraksi payload dalam kode Anda sendiri. Tidak cocok untuk digunakan dalam produksi kode karena permintaan dapat terhambat atau mengalami error intermiten.

Untuk memvalidasi token ID menggunakan endpoint tokeninfo, buat HTTPS POST atau GET ke endpoint, dan teruskan token ID di Parameter id_token. Misalnya, untuk memvalidasi token "XYZ123", buat permintaan GET berikut:

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

Jika token ditandatangani dengan benar dan iss serta exp klaim memiliki nilai yang diharapkan, Anda akan mendapatkan respons HTTP 200, dengan bagian berisi klaim token ID berformat JSON. Berikut adalah contoh respons:

{
 // 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"
}

Jika perlu memvalidasi bahwa token ID mewakili akun Google Workspace, Anda dapat memeriksanya klaim hd, yang menunjukkan domain pengguna yang dihosting. Ini harus digunakan saat membatasi akses ke sumber daya hanya untuk anggota domain tertentu. Tidak adanya klaim ini menunjukkan bahwa akun tersebut tidak termasuk dalam domain yang dihosting Google Workspace.