Если вы поддерживаете вход с аккаунтом Google, то можете использовать клиент для входа через One Tap, чтобы пользователи могли легко создавать аккаунты, не выходя из приложения.
Когда вы показываете интерфейс One Tap, пользователям предлагается создать новый аккаунт в вашем приложении, используя один из аккаунтов Google на их устройстве. Если пользователь решит продолжить, вы получите токен идентификации с основными сведениями профиля: именем, фото профиля и подтвержденным адресом электронной почты. Эти данные можно использовать для создания нового аккаунта.
Реализация регистрации в одно касание состоит из двух частей:
- Интеграция клиента One Tap в ваше приложение, которая описана на этой странице. Это похоже на вход через One Tap, но есть некоторые различия в настройке.
- Добавление в серверную часть возможности создавать аккаунты пользователей на основе токенов идентификации Google. Подробнее об этом рассказывается в разделе Использование токенов идентификации в серверной части.
Где следует использовать регистрацию через One Tap?
Лучше всего предлагать регистрацию через One Tap в контексте, где вход в аккаунт открывает доступ к новым функциям. Сначала попробуйте выполнить вход пользователя с помощью сохраненных учетных данных. Если сохраненных учетных данных нет, предложите пользователю создать аккаунт.
Подготовка
Настройте проект в консоли Google Cloud и проект для Android, как описано в статье Начало работы с входом через One Tap.
1. Настройте клиент One Tap
Чтобы настроить клиент One Tap для создания аккаунта, выполните следующие действия:
- Не включать запросы на ввод пароля. Регистрация в одно касание возможна только при аутентификации на основе токенов.
Включите запросы токенов идентификации Google с помощью
setGoogleIdTokenRequestOptions()и следующих настроек:- Укажите идентификатор клиента сервера, созданный в консоли Google Cloud. Обратите внимание, что это идентификатор клиента сервера, а не Android.
- Настройте клиент так, чтобы он показывал все аккаунты Google на устройстве, то есть не фильтровал их по авторизованным аккаунтам.
- Вы также можете запросить подтвержденный номер телефона для аккаунта.
Java
public class YourActivity extends AppCompatActivity {
// ...
private SignInClient oneTapClient;
private BeginSignInRequest signUpRequest;
@Override
public void onCreate(@Nullable Bundle savedInstanceState,
@Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
oneTapClient = Identity.getSignInClient(this);
signUpRequest = BeginSignInRequest.builder()
.setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder()
.setSupported(true)
// Your server's client ID, not your Android client ID.
.setServerClientId(getString(R.string.your_web_client_id))
// Show all accounts on the device.
.setFilterByAuthorizedAccounts(false)
.build())
.build();
// ...
}
}
Kotlin
class YourActivity : AppCompatActivity() {
// ...
private lateinit var oneTapClient: SignInClient
private lateinit var signUpRequest: BeginSignInRequest
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
oneTapClient = Identity.getSignInClient(this)
signUpRequest = BeginSignInRequest.builder()
.setGoogleIdTokenRequestOptions(
BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
.setSupported(true)
// Your server's client ID, not your Android client ID.
.setServerClientId(getString(R.string.your_web_client_id))
// Show all accounts on the device.
.setFilterByAuthorizedAccounts(false)
.build())
.build()
// ...
}
// ...
}
2. Как отслеживать отмену входа в One Tap
Вам следует отслеживать, отказался ли пользователь от регистрации через One Tap, закрыв окно или нажав за его пределами. Например, можно использовать логическое свойство Activity. (см. раздел Как отключить показ интерфейса One Tap ниже).
3. Как показать интерфейс регистрации через One Tap
Если пользователь не отказался от создания аккаунта в одно касание, вызовите метод beginSignIn() объекта клиента и прикрепите прослушиватели к возвращаемому объекту Task. Обычно приложения выполняют этот шаг, когда запрос на вход через One Tap не находит сохраненных учетных данных, то есть в прослушивателе сбоев запроса на вход.
- Прослушиватель успешного выполнения. Клиент One Tap вызывает прослушиватель успешного выполнения, если на устройстве пользователя настроен один или несколько аккаунтов Google. В прослушивателе успешного выполнения получите отложенный интент из результата
Taskи передайте его вstartIntentSenderForResult(), чтобы запустить интерфейс One Tap. Прослушиватель сбоев. Если на устройстве пользователя нет аккаунтов Google, клиент One Tap вызывает прослушиватель сбоев. В этом случае никаких действий не требуется: продолжайте показывать пользователю интерфейс приложения без входа в аккаунт, и он сможет зарегистрироваться в обычном порядке.
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 Google Accounts found. Just continue presenting the signed-out UI.
Log.d(TAG, e.getLocalizedMessage());
}
});
Kotlin
oneTapClient.beginSignIn(signUpRequest)
.addOnSuccessListener(this) { result ->
try {
startIntentSenderForResult(
result.pendingIntent.intentSender, REQ_ONE_TAP,
null, 0, 0, 0)
} catch (e: IntentSender.SendIntentException) {
Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
}
}
.addOnFailureListener(this) { e ->
// No Google Accounts found. Just continue presenting the signed-out UI.
Log.d(TAG, e.localizedMessage)
}
4. Обработка ответа пользователя
Ответ пользователя на запрос регистрации через One Tap будет передан в ваше приложение с помощью метода onActivityResult(). Если пользователь решил создать аккаунт, результатом будет токен идентификатора Google. Если пользователь отказался от регистрации, закрыв интерфейс One Tap или нажав за его пределами, будет возвращен код RESULT_CANCELED. Приложение должно быть готово к обоим вариантам.
Как создать аккаунт с помощью токена идентификатора Google
Если пользователь решил зарегистрироваться с помощью аккаунта Google, вы можете получить для него токен идентификатора, передав данные о намерении из onActivityResult() в метод getSignInCredentialFromIntent() клиента One Tap. Учетные данные будут иметь ненулевое свойство googleIdToken.
Используйте токен идентификации, чтобы создать аккаунт на бэкенде (см. раздел Выполнить аутентификацию на бэкенде с помощью токенов идентификации) и выполнить вход пользователя.
Учетные данные также содержат любые дополнительные сведения, которые вы запросили, например подтвержденный номер телефона аккаунта, если он доступен.
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();
if (idToken != null) {
// Got an ID token from Google. Use it to authenticate
// with your backend.
Log.d(TAG, "Got ID token.");
}
} 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
when {
idToken != null -> {
// Got an ID token from Google. Use it to authenticate
// with your backend.
Log.d(TAG, "Got ID token.")
}
else -> {
// Shouldn't happen.
Log.d(TAG, "No ID token!")
}
}
} catch (e: ApiException) {
// ...
}
}
}
// ...
}
Как отключить интерфейс One Tap
Если пользователь отказался от входа, вызов getSignInCredentialFromIntent() выдаст ApiException с кодом статуса CommonStatusCodes.CANCELED.
В этом случае следует временно прекратить показ интерфейса входа через One Tap, чтобы не раздражать пользователей повторяющимися запросами. В примере ниже это делается путем настройки свойства в Activity, которое используется для определения того, предлагать ли пользователю вход через One Tap. Однако вы также можете сохранить значение в SharedPreferences или использовать другой метод.
Важно реализовать собственное ограничение частоты запросов на вход через One Tap. Если вы этого не сделаете и пользователь отменит несколько запросов подряд, клиент One Tap не будет запрашивать у пользователя следующие 24 часа.
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})")
}
}
}
}
}
}
// ...
}
Дальнейшие действия
Когда пользователь завершает регистрацию через One Tap, вы получаете токен идентификатора Google, который содержит основную информацию профиля: адрес электронной почты, полное имя и URL фото профиля. Для многих приложений этой информации достаточно, чтобы выполнить аутентификацию пользователя на сервере и создать аккаунт.
Если для создания аккаунта вам нужна дополнительная информация, например дата рождения пользователя, запросите ее на этапе регистрации, а затем отправьте на сервер.