Если вы поддерживаете вход с помощью учетных записей Google, вы можете использовать клиент входа в One Tap, чтобы предоставить пользователям возможность легкого создания учетных записей, которая никогда не выведет их из контекста вашего приложения.
Когда вы отображаете пользовательский интерфейс One Tap, пользователям предлагается создать новую учетную запись в вашем приложении, используя одну из учетных записей Google на своем устройстве. Если пользователь решит продолжить, вы получите идентификационный токен с основной информацией профиля — его именем, фотографией профиля и подтвержденным адресом электронной почты — который вы можете использовать для создания новой учетной записи.
Реализация создания учетной записи One Tap состоит из двух частей:
- Интеграция клиента One Tap в ваше приложение, описанная на этой странице. По сути, это то же самое, что и вход в систему одним касанием, но с некоторыми отличиями в конфигурации.
- Добавление в ваш бэкэнд возможности создавать учетные записи пользователей из токенов Google ID, что обсуждается в разделе Использование токенов ID на бэкэнде .
Где мне следует использовать регистрацию One Tap?
Наиболее эффективно предлагать пользователям регистрацию в одно касание в контексте, когда вход в систему открывает доступ к новым функциям. Сначала попробуйте войти в систему, используя сохраненные учетные данные. Если сохраненные учетные данные не найдены, предложите создать новую учетную запись для пользователя.
Прежде чем начать
Настройте проект консоли API Google и проект Android, как описано в разделе Начало работы с входом в одно касание .
1. Настройте клиент One Tap.
Чтобы настроить клиент One Tap для создания учетной записи, выполните следующие действия:
- Не включайте запросы учетных данных пароля. (Регистрация в одно касание возможна только при аутентификации на основе токенов.)
Включите запросы токенов идентификатора Google, используя
setGoogleIdTokenRequestOptions()
и следующие настройки:- Установите идентификатор клиента сервера на идентификатор, который вы создали в консоли Google API . Обратите внимание, что это идентификатор клиента вашего сервера, а не идентификатор клиента Android.
- Настройте клиент для отображения всех учетных записей Google на устройстве, то есть не фильтруйте по авторизованным учетным записям.
- При желании вы также можете запросить подтвержденный номер телефона для учетной записи.
Ява
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(); // ... } }
Котлин
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» ниже.)
3. Отображение пользовательского интерфейса регистрации в одно касание.
Если пользователь не отказался использовать One Tap для создания новой учетной записи, вызовите метод beginSignIn()
клиентского объекта и прикрепите прослушиватели к возвращаемой Task
. Приложения обычно выполняют этот шаг, когда запрос на вход в One Tap не находит сохраненных учетных данных, то есть в прослушивателе ошибок запроса на вход.
Клиент One Tap вызовет прослушиватель успехов, если у пользователя на устройстве настроена одна или несколько учетных записей Google. В прослушивателе успеха получите ожидающее намерение из результата Task
и передайте его в startIntentSenderForResult()
чтобы запустить пользовательский интерфейс One Tap.
Если у пользователя нет учетных записей Google на устройстве, клиент One Tap вызовет прослушиватель ошибок. В этом случае никаких действий не требуется: вы можете просто продолжать демонстрировать опыт выхода из приложения, а пользователь может зарегистрироваться, используя обычный процесс создания учетной записи.
Ява
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());
}
});
Котлин
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. Обработка ответа пользователя
Ответ пользователя на приглашение на регистрацию в одно касание будет передан в ваше приложение с помощью метода onActivityResult()
вашего действия. Если пользователь решил создать учетную запись, результатом будет токен Google ID. Если пользователь отказался зарегистрироваться, закрыв пользовательский интерфейс One Tap или нажав за его пределами, результат вернется с кодом RESULT_CANCELED
. Ваше приложение должно обрабатывать обе возможности.
Создайте учетную запись с помощью токена Google ID.
Если пользователь решил зарегистрироваться с помощью учетной записи Google, вы можете получить токен идентификатора для пользователя, передав данные о намерении из onActivityResult()
в метод getSignInCredentialFromIntent()
клиента One Tap. Учетные данные будут иметь свойство googleIdToken
, отличное от NULL.
Используйте токен идентификатора, чтобы создать учетную запись на своем сервере (см. Аутентификация с помощью сервера с использованием токенов идентификатора ) и войдите в систему пользователя.
Учетные данные также содержат любую запрошенную вами дополнительную информацию, например подтвержденный номер телефона учетной записи, если он доступен.
Ява
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; } } }
Котлин
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
. В этом случае вам следует временно прекратить отображение пользовательского интерфейса входа в систему одним касанием, чтобы не раздражать пользователей повторяющимися запросами. В следующем примере это достигается путем установки свойства действия, которое используется для определения того, предлагать ли пользователю вход в систему одним касанием; однако вы также можете сохранить значение в SharedPreferences
или использовать какой-либо другой метод.
Важно реализовать собственное ограничение скорости запросов на вход в систему одним касанием. Если вы этого не сделаете и пользователь отменит несколько запросов подряд, клиент One Tap не будет отправлять пользователю запросы в течение следующих 24 часов.
Ява
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; } } }
Котлин
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})") } } } } } } // ... }
Следующие шаги
Когда пользователь завершает процесс регистрации в одно касание, вы получаете токен Google ID, который включает в себя некоторую базовую информацию профиля: адрес электронной почты пользователя, полное имя и URL-адрес изображения профиля. Для многих приложений этой информации достаточно, чтобы аутентифицировать пользователя на серверной стороне и создать новую учетную запись.
Если для завершения создания учетной записи вам требуется дополнительная информация — например, дата рождения пользователя — предоставьте пользователю поток сведений о регистрации, в котором вы запросите эту дополнительную информацию. Затем отправьте его на свой сервер, чтобы завершить создание учетной записи.