Gunakan klien login Sekali Ketuk untuk meminta izin dari pengguna guna mengambil salah satu kredensial yang sebelumnya mereka gunakan untuk login ke aplikasi Anda. Kredensial ini dapat berupa Akun Google atau kombinasi nama pengguna dan sandi yang disimpan dengan Google menggunakan Chrome, isi otomatis Android, atau Smart Lock untuk Sandi.
Jika kredensial berhasil diambil, Anda dapat menggunakannya untuk membuat pengguna login dengan lancar ke aplikasi Anda.
Jika pengguna belum menyimpan kredensial apa pun, tidak akan ada UI yang ditampilkan, dan Anda dapat memberikan pengalaman logout normal.
Di mana saya harus menggunakan login Sekali Ketuk?
Jika aplikasi Anda mengharuskan pengguna untuk login, tampilkan UI Sekali Ketuk di layar login. Ini dapat membantu meskipun Anda sudah memiliki tombol "Login dengan Google" : karena UI Sekali Ketuk dapat dikonfigurasi untuk hanya menampilkan kredensial yang sebelumnya digunakan pengguna untuk login, UI ini dapat menjadi pengingat bagi pengguna yang jarang login saat mereka login terakhir kali, dan mencegahnya membuat akun baru secara tidak sengaja dengan aplikasi Anda.
Jika login bersifat opsional untuk aplikasi Anda, pertimbangkan untuk menggunakan login Sekali Ketuk di layar mana pun yang memiliki pengalaman yang ditingkatkan dengan login. Misalnya, jika pengguna dapat menjelajahi konten dengan aplikasi Anda saat logout, tetapi hanya dapat memposting komentar atau menambahkan item ke keranjang belanja setelah login, itu akan menjadi konteks yang masuk akal untuk login Sekali Ketuk.
Aplikasi opsional login juga harus menggunakan login Sekali Ketuk di layar login karena alasan yang disebutkan di atas.
Sebelum memulai
- Siapkan project konsol Google API dan project Android Anda seperti yang dijelaskan dalam Mulai login dengan Sekali Ketuk.
- Jika Anda mendukung login berbasis sandi, optimalkan aplikasi Anda untuk isi otomatis (atau gunakan Smart Lock untuk Sandi) agar pengguna dapat menyimpan kredensial sandi mereka setelah login.
1. Mengonfigurasi klien login Sekali Ketuk
Anda dapat mengonfigurasi klien login dengan Sekali Ketuk untuk membuat pengguna login dengan sandi tersimpan, Akun Google tersimpan, atau keduanya. (Mendukung keduanya direkomendasikan, untuk mengaktifkan pembuatan akun sekali ketuk untuk pengguna baru dan login otomatis atau sekali ketuk untuk sebanyak mungkin pengguna yang kembali.)
Jika aplikasi Anda menggunakan login berbasis sandi, gunakan setPasswordRequestOptions()
untuk
mengaktifkan permintaan kredensial sandi.
Jika aplikasi Anda menggunakan Login dengan Google, gunakan setGoogleIdTokenRequestOptions()
untuk mengaktifkan dan mengonfigurasi permintaan token ID Google:
Setel client ID server ke ID yang Anda buat di konsol Google API. Perhatikan bahwa ini adalah client ID server Anda, bukan client ID Android Anda.
Konfigurasikan klien untuk memfilter berdasarkan akun yang diotorisasi. Jika Anda mengaktifkan opsi ini, klien Sekali Ketuk hanya akan meminta pengguna untuk login ke aplikasi Anda dengan Akun Google yang telah digunakan sebelumnya. Cara ini dapat membantu pengguna berhasil login saat mereka tidak yakin apakah mereka sudah memiliki akun atau Akun Google mana yang digunakan, dan mencegah pengguna membuat akun baru dengan aplikasi Anda secara tidak sengaja.
Jika Anda ingin membuat pengguna login secara otomatis jika memungkinkan, aktifkan fitur tersebut dengan
setAutoSelectEnabled()
. Login otomatis dapat dilakukan jika kriteria berikut terpenuhi:- Pengguna memiliki tepat satu kredensial yang disimpan untuk aplikasi Anda. Artinya, satu sandi tersimpan atau satu Akun Google tersimpan.
- Pengguna belum menonaktifkan login otomatis di setelan Akun Google mereka.
Meskipun opsional, sebaiknya Anda mempertimbangkan untuk menggunakan nonce guna meningkatkan keamanan login dan menghindari serangan replay. Gunakan setNonce untuk menyertakan nonce di setiap permintaan. Lihat bagian Mendapatkan nonce dari SafetyNet untuk saran dan detail tambahan tentang cara membuat nonce.
Java
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. Memeriksa pengguna yang login
Jika Aktivitas Anda dapat digunakan oleh pengguna yang login atau pengguna yang logout, periksa status pengguna sebelum menampilkan UI login Sekali Ketuk.
Anda juga harus memantau apakah pengguna sudah menolak menggunakan login Sekali Ketuk dengan menutup perintah atau mengetuk di luarnya. Hal ini bisa sesederhana properti boolean Aktivitas Anda. (Lihat Berhenti menampilkan UI Sekali Ketuk di bawah.)
3. Menampilkan UI login Sekali Ketuk
Jika pengguna belum login dan belum menolak untuk menggunakan login Sekali Ketuk,
panggil metode beginSignIn()
objek klien dan lampirkan pemroses ke
Task
yang ditampilkannya. Aplikasi biasanya melakukan ini di metode onCreate()
Aktivitas
atau setelah transisi layar saat menggunakan arsitektur Activity tunggal.
Klien Sekali Ketuk akan memanggil pemroses yang berhasil jika pengguna memiliki kredensial yang disimpan untuk aplikasi Anda. Pada pemroses yang berhasil, dapatkan intent yang tertunda dari hasil Task
dan teruskan ke startIntentSenderForResult()
untuk memulai UI login Sekali Ketuk.
Jika pengguna tidak memiliki kredensial yang disimpan, klien Sekali Ketuk akan memanggil pemroses yang gagal. Dalam hal ini, Anda tidak perlu melakukan tindakan apa pun: Anda dapat terus menyajikan pengalaman logout aplikasi. Namun, jika Anda mendukung pendaftaran Sekali Ketuk, Anda dapat memulai alur tersebut di sini untuk pengalaman pembuatan akun yang lancar. Lihat Membuat akun baru dengan sekali ketuk.
Java
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. Menangani respons pengguna
Respons pengguna terhadap perintah login Sekali Ketuk akan dilaporkan ke aplikasi Anda
menggunakan metode onActivityResult()
Aktivitas Anda. Jika pengguna memilih untuk login, hasilnya adalah kredensial yang disimpan. Jika pengguna menolak untuk login, baik dengan menutup UI Sekali Ketuk maupun mengetuk di luarnya, hasilnya akan ditampilkan dengan kode RESULT_CANCELED
. Aplikasi Anda harus menangani kedua kemungkinan yang ada.
Login dengan kredensial yang diambil
Jika pengguna memilih untuk berbagi kredensial dengan aplikasi, Anda dapat mengambilnya dengan
meneruskan data intent dari onActivityResult()
ke metode
getSignInCredentialFromIntent()
klien Sekali Ketuk. Kredensial akan memiliki properti googleIdToken
non-null jika pengguna membagikan kredensial Akun Google ke aplikasi Anda, atau properti password
non-null jika pengguna membagikan sandi yang tersimpan.
Gunakan kredensial untuk mengautentikasi dengan backend aplikasi Anda.
- Jika pasangan nama pengguna dan sandi diambil, gunakan untuk login dengan cara yang sama seperti jika pengguna telah memberikan keduanya secara manual.
Jika kredensial Akun Google diambil, gunakan token ID untuk melakukan autentikasi dengan backend Anda. Jika Anda memilih untuk menggunakan nonce guna membantu menghindari serangan replay, periksa nilai respons di server backend Anda. Baca bagian Mengautentikasi dengan backend menggunakan token ID.
Java
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 UI Sekali Ketuk
Jika pengguna menolak untuk login, panggilan ke getSignInCredentialFromIntent()
akan memunculkan ApiException
dengan kode status CommonStatusCodes.CANCELED
.
Jika hal ini terjadi, Anda harus menonaktifkan UI login Sekali Ketuk untuk sementara agar
tidak mengganggu pengguna dengan perintah berulang. Contoh berikut melakukan hal ini dengan menetapkan properti di Aktivitas, yang digunakan untuk menentukan apakah akan menawarkan login Sekali Ketuk kepada pengguna atau tidak; namun, Anda juga dapat menyimpan nilai ke SharedPreferences
atau menggunakan beberapa metode lainnya.
Sangat penting untuk menerapkan pembatasan kapasitas Anda sendiri terhadap perintah login Sekali Ketuk. Jika Anda tidak melakukannya, dan pengguna membatalkan beberapa perintah secara berturut-turut, klien Sekali Ketuk tidak akan memintanya selama 24 jam berikutnya.
Java
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 logout
Saat pengguna logout dari aplikasi Anda, panggil metode signOut()
klien Sekali Ketuk.
Memanggil signOut()
akan menonaktifkan login otomatis sampai pengguna login lagi.
Meskipun Anda tidak menggunakan login otomatis, langkah ini penting karena akan memastikan bahwa saat pengguna logout dari aplikasi, status autentikasi setiap API layanan Play yang Anda gunakan juga direset.
Langkah berikutnya
Jika Anda mengonfigurasi klien Sekali Ketuk untuk mengambil kredensial Google, aplikasi Anda kini dapat memperoleh token ID Google yang mewakili Akun Google pengguna. Pelajari cara menggunakan token ini di backend.
Jika mendukung Login dengan Google, Anda juga dapat menggunakan klien Sekali Ketuk untuk menambahkan alur pembuatan akun tanpa hambatan ke aplikasi Anda.