Peringatan: Data ini disediakan menurut Kebijakan Data Pengguna Google . Harap tinjau dan patuhi kebijakan. Kegagalan untuk melakukannya dapat mengakibatkan penangguhan proyek atau penangguhan akun.

Masuk pengguna dengan kredensial mereka yang disimpan

Gunakan klien masuk Satu Ketuk untuk meminta izin dari pengguna untuk mengambil salah satu kredensial yang sebelumnya mereka gunakan untuk masuk ke aplikasi Anda. Kredensial ini dapat berupa Akun Google atau kombinasi nama pengguna-sandi yang disimpan dengan Google menggunakan Chrome, IsiOtomatis Android, atau Smart Lock untuk Sandi.

UI masuk sekali ketuk

Saat kredensial berhasil diambil, Anda dapat menggunakannya untuk membuat pengguna masuk ke aplikasi Anda dengan mudah.

Jika pengguna belum menyimpan kredensial apa pun, tidak ada UI yang ditampilkan, dan Anda dapat memberikan pengalaman logout yang normal.

Di mana saya harus menggunakan login Satu Ketuk?

Jika aplikasi Anda mengharuskan pengguna untuk masuk, tampilkan UI Satu Ketukan di layar masuk Anda. Ini dapat membantu bahkan jika Anda sudah memiliki tombol "Masuk dengan Google": karena UI Satu Ketukan dapat dikonfigurasi untuk hanya menampilkan kredensial yang sebelumnya digunakan pengguna untuk masuk, ini dapat menjadi pengingat bagi pengguna yang jarang masuk bagaimana mereka masuk terakhir kali, dan mencegah mereka membuat akun baru secara tidak sengaja dengan aplikasi Anda.

Jika sign-in adalah opsional untuk aplikasi Anda, pertimbangkan untuk menggunakan One Tap sign-in di layar mana pun yang memiliki pengalaman yang disempurnakan dengan masuk. Misalnya, jika pengguna dapat menelusuri konten dengan aplikasi Anda saat keluar, tetapi hanya dapat mengeposkan komentar atau menambahkan item ke keranjang belanja setelah masuk, itu akan menjadi konteks yang masuk akal untuk masuk dengan Satu Ketukan.

Aplikasi opsional masuk juga harus menggunakan masuk Sekali Ketuk di layar masuk mereka, untuk alasan yang disebutkan di atas.

Sebelum kamu memulai

1. Konfigurasikan klien masuk Satu Ketuk

Anda dapat mengonfigurasi klien masuk One Tap untuk memasukkan pengguna dengan sandi tersimpan, Akun Google tersimpan, atau keduanya. (Disarankan untuk mendukung keduanya, untuk mengaktifkan pembuatan akun sekali ketuk untuk pengguna baru dan masuk otomatis atau sekali ketuk untuk sebanyak mungkin pengguna yang kembali.)

Jika menggunakan aplikasi Anda masuk berbasis password, gunakan setPasswordRequestOptions() untuk memungkinkan permintaan credential password.

Jika aplikasi Anda menggunakan Google Sign-in, penggunaan setGoogleIdTokenRequestOptions() untuk mengaktifkan dan mengkonfigurasi Google ID permintaan tanda:

  • Mengatur ID client server untuk ID yang Anda buat di konsol Google API . Perhatikan ini adalah ID klien server Anda, bukan ID klien Android Anda.

  • Konfigurasikan klien untuk memfilter menurut akun resmi. Saat Anda mengaktifkan opsi ini, klien One Tap hanya meminta pengguna untuk masuk ke aplikasi Anda dengan Akun Google yang telah mereka gunakan sebelumnya. Melakukannya dapat membantu pengguna berhasil masuk saat mereka tidak yakin apakah mereka sudah memiliki akun atau Akun Google mana yang mereka gunakan, dan mencegah pengguna membuat akun baru secara tidak sengaja dengan aplikasi Anda.

  • Jika Anda ingin mendaftar pengguna secara otomatis bila memungkinkan, mengaktifkan fitur dengan setAutoSelectEnabled() . Masuk otomatis dimungkinkan jika kriteria berikut terpenuhi:

    • Pengguna memiliki tepat satu kredensial yang disimpan untuk aplikasi Anda. Artinya, satu sandi tersimpan atau satu Akun Google tersimpan.
    • Pengguna tidak dinonaktifkan masuk otomatis dalam mereka pengaturan Akun Google .
  • Meskipun opsional, sebaiknya Anda sangat mempertimbangkan untuk menggunakan nonce untuk meningkatkan keamanan masuk dan menghindari serangan replay. Gunakan setNonce untuk menyertakan Nonce di setiap permintaan. Lihat SafetyNet Ini Mendapatkan Nonce bagian untuk saran dan detail tambahan tentang menghasilkan Nonce a.

Jawa

public class YourActivity extends AppCompatActivity {
  // ...

  private SignInClient oneTapClient;
  private BeginSignInRequest signInRequest;

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState,
                       @Nullable PersistableBundle persistentState) {
      super.onCreate(savedInstanceState, persistentState);

      oneTapClient = Identity.getSignInClient(this);
      signInRequest = BeginSignInRequest.builder()
              .setPasswordRequestOptions(PasswordRequestOptions.builder()
                      .setSupported(true)
                      .build())
              .setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder()
                      .setSupported(true)
                      // Your server's client ID, not your Android client ID.
                      .setServerClientId(getString(R.string.default_web_client_id))
                      // Only show accounts previously used to sign in.
                      .setFilterByAuthorizedAccounts(true)
                      .build())
              // Automatically sign in when exactly one credential is retrieved.
              .setAutoSelectEnabled(true)
              .build();
      // ...
  }
  // ...
}

Kotlin

class YourActivity : AppCompatActivity() {
    // ...

    private lateinit var oneTapClient: SignInClient
    private lateinit var signInRequest: BeginSignInRequest

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        oneTapClient = Identity.getSignInClient(this)
        signInRequest = BeginSignInRequest.builder()
            .setPasswordRequestOptions(BeginSignInRequest.PasswordRequestOptions.builder()
                .setSupported(true)
                .build())
            .setGoogleIdTokenRequestOptions(
                BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                    .setSupported(true)
                    // Your server's client ID, not your Android client ID.
                    .setServerClientId(getString(R.string.your_web_client_id))
                    // Only show accounts previously used to sign in.
                    .setFilterByAuthorizedAccounts(true)
                    .build())
            // Automatically sign in when exactly one credential is retrieved.
            .setAutoSelectEnabled(true)
            .build()
        // ...
    }
    // ...
}

2. Periksa pengguna yang masuk

Jika Aktivitas Anda dapat digunakan oleh pengguna yang masuk atau pengguna yang keluar, periksa status pengguna sebelum menampilkan UI masuk Sekali Ketuk.

Anda juga harus melacak apakah pengguna telah menolak untuk menggunakan fitur masuk Sekali Ketuk dengan menutup perintah atau mengetuk di luarnya. Ini bisa sesederhana properti boolean dari Aktivitas Anda. (Lihat Berhenti menampilkan Satu Tap UI , di bawah ini.)

3. Tampilkan UI masuk Sekali Ketuk

Jika pengguna tidak masuk dan belum sudah menolak untuk menggunakan One Tap masuk, memanggil objek klien beginSignIn() metode, dan melampirkan pendengar ke Task itu kembali. Aplikasi biasanya melakukan hal ini dalam Kegiatan ini onCreate() metode atau setelah transisi layar saat menggunakan arsitektur single-Activity.

Klien One Tap akan memanggil pendengar yang berhasil jika pengguna memiliki kredensial yang disimpan untuk aplikasi Anda. Dalam pendengar sukses, dapatkan maksud tertunda dari Task hasil dan menyebarkannya ke startIntentSenderForResult() untuk memulai Satu Tap masuk UI.

Jika pengguna tidak memiliki kredensial yang disimpan, klien One Tap akan memanggil pendengar kegagalan. Dalam hal ini, tidak ada tindakan yang diperlukan: Anda cukup melanjutkan menyajikan pengalaman keluar aplikasi. Namun, jika Anda mendukung pendaftaran Satu Ketuk, Anda dapat memulai alur itu di sini untuk pengalaman pembuatan akun yang lancar. Lihat Buat account baru dengan satu tekan .

Jawa

oneTapClient.beginSignIn(signUpRequest)
        .addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
            @Override
            public void onSuccess(BeginSignInResult result) {
                try {
                    startIntentSenderForResult(
                            result.getPendingIntent().getIntentSender(), REQ_ONE_TAP,
                            null, 0, 0, 0);
                } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
                }
            }
        })
        .addOnFailureListener(this, new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // No saved credentials found. Launch the One Tap sign-up flow, or
                // do nothing and continue presenting the signed-out UI.
                Log.d(TAG, e.getLocalizedMessage());
            }
        });

Kotlin

oneTapClient.beginSignIn(signInRequest)
    .addOnSuccessListener(this) { result ->
        try {
            startIntentSenderForResult(
                result.pendingIntent.intentSender, REQ_ONE_TAP,
                null, 0, 0, 0, null)
        } catch (e: IntentSender.SendIntentException) {
            Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
        }
    }
    .addOnFailureListener(this) { e ->
        // No saved credentials found. Launch the One Tap sign-up flow, or
        // do nothing and continue presenting the signed-out UI.
        Log.d(TAG, e.localizedMessage)
    }

4. Tangani respons pengguna

Tanggapan pengguna untuk Satu Tap masuk prompt akan dilaporkan ke aplikasi Anda menggunakan Activity Anda onActivityResult() metode. Jika pengguna memilih untuk masuk, hasilnya akan menjadi kredensial yang disimpan. Jika pengguna menolak untuk masuk, baik dengan menutup Satu Tap UI atau penyadapan di luar itu, hasilnya akan kembali dengan kode RESULT_CANCELED . Aplikasi Anda perlu menangani kedua kemungkinan tersebut.

Masuk dengan kredensial yang diambil

Jika pengguna memilih untuk kredensial berbagi dengan aplikasi Anda, Anda dapat mengambil mereka dengan melewati data maksud dari onActivityResult() ke Satu Tap klien getSignInCredentialFromIntent() metode. Credential akan memiliki non-null googleIdToken properti jika pengguna berbagi credential Akun Google dengan aplikasi Anda, atau non-null password properti jika pengguna berbagi sandi disimpan.

Gunakan kredensial untuk mengautentikasi dengan backend aplikasi Anda.

  • Jika pasangan nama pengguna dan sandi diambil, gunakan untuk masuk dengan cara yang sama seperti yang Anda lakukan jika pengguna telah memberikannya secara manual.
  • Jika kredensial Akun Google diambil, gunakan token ID untuk mengautentikasi dengan backend Anda. Jika Anda memilih untuk menggunakan nonce untuk membantu menghindari serangan replay, periksa nilai respons di server backend Anda. Lihat Otentikasi dengan backend menggunakan token ID .

Jawa

public class YourActivity extends AppCompatActivity {

  // ...
  private static final int REQ_ONE_TAP = 2;  // Can be any integer unique to the Activity.
  private boolean showOneTapUI = true;
  // ...

  @Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
      super.onActivityResult(requestCode, resultCode, data);

      switch (requestCode) {
          case REQ_ONE_TAP:
              try {
                  SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(data);
                  String idToken = credential.getGoogleIdToken();
                  String username = credential.getId();
                  String password = credential.getPassword();
                  if (idToken !=  null) {
                      // Got an ID token from Google. Use it to authenticate
                      // with your backend.
                      Log.d(TAG, "Got ID token.");
                  } else if (password != null) {
                      // Got a saved username and password. Use them to authenticate
                      // with your backend.
                      Log.d(TAG, "Got password.");
                  }
              } catch (ApiException e) {
                  // ...
              }
              break;
      }
  }
}

Kotlin

class YourActivity : AppCompatActivity() {

    // ...
    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private var showOneTapUI = true
    // ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
             REQ_ONE_TAP -> {
                try {
                    val credential = oneTapClient.getSignInCredentialFromIntent(data)
                    val idToken = credential.googleIdToken
                    val username = credential.id
                    val password = credential.password
                    when {
                        idToken != null -> {
                            // Got an ID token from Google. Use it to authenticate
                            // with your backend.
                            Log.d(TAG, "Got ID token.")
                        }
                        password != null -> {
                            // Got a saved username and password. Use them to authenticate
                            // with your backend.
                            Log.d(TAG, "Got password.")
                        }
                        else -> {
                            // Shouldn't happen.
                            Log.d(TAG, "No ID token or password!")
                        }
                    }
                } catch (e: ApiException) {
                    // ...
                }
            }
        }
    }
    // ...
}

Berhenti menampilkan One Tap UI

Jika pengguna menolak untuk masuk, panggilan untuk getSignInCredentialFromIntent() akan melempar ApiException dengan CommonStatusCodes.CANCELED kode status. Ketika ini terjadi, Anda harus menonaktifkan sementara UI masuk dengan Satu Ketukan sehingga Anda tidak mengganggu pengguna dengan perintah berulang. Contoh berikut menyelesaikannya dengan menyetel properti pada Aktivitas, yang digunakannya untuk menentukan apakah akan menawarkan masuk dengan Satu Ketukan kepada pengguna; Namun, Anda juga bisa menyimpan nilai SharedPreferences atau menggunakan beberapa metode lain.

Penting untuk menerapkan pembatasan tarif Anda sendiri untuk permintaan masuk dengan Satu Ketukan. Jika tidak, dan pengguna membatalkan beberapa perintah berturut-turut, klien Satu Ketuk tidak akan meminta pengguna selama 24 jam berikutnya.

Jawa

public class YourActivity extends AppCompatActivity {

  // ...
  private static final int REQ_ONE_TAP = 2;  // Can be any integer unique to the Activity.
  private boolean showOneTapUI = true;
  // ...

  @Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
      super.onActivityResult(requestCode, resultCode, data);

      switch (requestCode) {
          case REQ_ONE_TAP:
              try {
                  // ...
              } catch (ApiException e) {
                  switch (e.getStatusCode()) {
                      case CommonStatusCodes.CANCELED:
                          Log.d(TAG, "One-tap dialog was closed.");
                          // Don't re-prompt the user.
                          showOneTapUI = false;
                          break;
                      case CommonStatusCodes.NETWORK_ERROR:
                          Log.d(TAG, "One-tap encountered a network error.");
                          // Try again or just ignore.
                          break;
                      default:
                          Log.d(TAG, "Couldn't get credential from result."
                                  + e.getLocalizedMessage());
                          break;
                  }
              }
              break;
      }
  }
}

Kotlin

class YourActivity : AppCompatActivity() {

    // ...
    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private var showOneTapUI = true
    // ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
            REQ_ONE_TAP -> {
                try {
                    // ...
                } catch (e: ApiException) {
                    when (e.statusCode) {
                        CommonStatusCodes.CANCELED -> {
                            Log.d(TAG, "One-tap dialog was closed.")
                            // Don't re-prompt the user.
                            showOneTapUI = false
                        }
                        CommonStatusCodes.NETWORK_ERROR -> {
                            Log.d(TAG, "One-tap encountered a network error.")
                            // Try again or just ignore.
                        }
                        else -> {
                            Log.d(TAG, "Couldn't get credential from result." +
                                " (${e.localizedMessage})")
                        }
                    }
                }
            }
        }
    }
    // ...
}

5. Menangani keluar

Saat pengguna keluar dari aplikasi Anda, hubungi Satu Tap klien signOut() metode. Memanggil signOut() menonaktifkan masuk otomatis sampai pengguna masuk lagi.

Meskipun Anda tidak menggunakan proses masuk otomatis, langkah ini penting karena memastikan bahwa saat pengguna keluar dari aplikasi Anda, status autentikasi dari semua API layanan Play yang Anda gunakan juga disetel ulang.

Langkah selanjutnya

Jika Anda mengonfigurasi klien One Tap untuk mengambil kredensial Google, aplikasi Anda sekarang bisa mendapatkan token ID Google yang mewakili Akun Google pengguna Anda. Pelajari bagaimana Anda dapat menggunakan token tersebut pada backend .

Jika Anda mendukung Google Sign-in, Anda juga dapat menggunakan klien Satu Sentuh untuk menambahkan pembuatan account gesekan mengalir ke aplikasi Anda .