Аутентификация на носимых устройствах: менеджер учетных данных

Приложения для Wear OS могут работать автономно, без сопутствующего приложения. Это означает, что при доступе к данным из интернета приложение для Wear OS должно самостоятельно управлять аутентификацией. Однако небольшой размер экрана и ограниченные возможности ввода на часах не позволяют использовать в приложениях для Wear OS все способы аутентификации.

В этом руководстве рассказывается о рекомендуемом способе аутентификации для приложений Wear OS – Менеджере учетных данных.

Чтобы узнать больше о том, как сделать процесс входа удобным, ознакомьтесь с руководством по UX для входа.

Предварительные соображения

Прежде чем начать реализацию, ознакомьтесь с приведенными ниже рекомендациями.

Гостевой режим

Не требуйте аутентификацию для всех функций. Вместо этого предоставьте пользователю как можно больше функций без необходимости входить в аккаунт.

Пользователи могут найти и установить приложение для Wear OS, не используя мобильное приложение, поэтому у них может не быть аккаунта и они могут не знать, какие функции предлагает приложение. Убедитесь, что гостевой режим позволяет корректно демонстрировать функции приложения.

Некоторые устройства могут оставаться разблокированными дольше

На поддерживаемых устройствах с Wear OS 5 или более поздней версии система определяет, носит ли пользователь устройство на запястье. Если пользователь отключит обнаружение запястья и снимет устройство, оно будет разблокировано дольше, чем обычно.

Если ваше приложение требует более высокого уровня безопасности, например при отображении конфиденциальных данных, сначала проверьте, включено ли обнаружение запястья:

fun isWristDetectionAutoLockingEnabled(context: Context): Boolean {
    // Use the keyguard manager to check for the presence of a lock mechanism
    val keyguardManager = context.getSystemService<KeyguardManager>()
    val isSecured = keyguardManager?.isDeviceSecure == true

    // Use OEM-specific system settings to verify that on-body autolock is enabled.
    val isWristDetectionOn = android.provider.Settings.Global.getInt(
        context.contentResolver, PIXEL_WRIST_AUTOLOCK_SETTING_STATE,
        0
    ) == 1

    return isSecured && isWristDetectionOn
}

Если метод возвращает значение false, предложите пользователю войти в аккаунт в приложении, прежде чем показывать контент, предназначенный для него.

Менеджер учетных данных

Менеджер учетных данных – это рекомендуемый API для аутентификации в Wear OS. Это позволяет пользователям входить в приложения Wear OS в автономном режиме, не подключая телефон и не вводя пароль.

В этом документе описаны сведения, необходимые разработчикам для реализации решения на основе Менеджера учетных данных со стандартными механизмами аутентификации, которые он поддерживает:

  • Ключи доступа
  • Пароли
  • Интегрированные идентификационные данные (например, функция "Войти с аккаунтом Google")

В этом руководстве также рассказывается, как перенести другие допустимые методы аутентификации Wear OS (передачу токенов через уровень данных и OAuth) в качестве резервных для Менеджера учетных данных, и приведены специальные инструкции по переходу с устаревшей отдельной кнопки входа с аккаунтом Google на встроенную версию Менеджера учетных данных.

Ограничения и различия в Wear OS

При разработке приложений для Wear OS учитывайте следующие ограничения и различия:

  • Менеджер учетных данных доступен в Wear OS 3 и более поздних версиях.
  • На устройствах Wear OS нельзя создавать учетные данные
  • Не поддерживаются ни восстановление учетных данных, ни гибридные способы входа.
  • Повторно использовать на мобильном устройстве можно только поставщиков учетных данных, интегрированных с Wear OS.

Ключи доступа на устройствах Wear OS

Мы настоятельно рекомендуем разработчикам реализовать поддержку ключей доступа в Менеджере учетных данных Wear OS. Ключи доступа – это новый отраслевой стандарт аутентификации конечных пользователей, который дает им ряд преимуществ.

Ключи доступа проще

  • Пользователи могут выбрать аккаунт для входа. Вводить имя пользователя не нужно.
  • Пользователи могут проходить аутентификацию с помощью способа разблокировки экрана устройства.
  • После создания и регистрации ключа доступа пользователь может перейти на новое устройство и сразу же начать им пользоваться без повторной регистрации.

Ключи доступа безопаснее

  • Разработчики сохраняют на сервере только открытый ключ, а не пароль. Это означает, что взлом серверов будет гораздо менее выгоден злоумышленникам, а в случае утечки данных потребуется гораздо меньше усилий для устранения ее последствий.
  • Ключи доступа обеспечивают защиту от фишинга. Ключи доступа работают только на зарегистрированных сайтах и в приложениях. Пользователя нельзя обманом заставить пройти аутентификацию на поддельном сайте, поскольку проверку выполняет браузер или ОС.
  • Ключи доступа позволяют не отправлять SMS, что делает аутентификацию более экономичной.

Как реализовать ключи доступа

Содержит инструкции по настройке и рекомендации для всех типов реализации.

Настроить

  1. Установите целевой уровень API 35 в файле build.gradle модуля приложения:

    android {
        defaultConfig {
            targetSdk(35)
        }
    }
    
  2. Добавьте в файл build.gradle для приложения или модуля следующие строки, используя последнюю стабильную версию из androidx.credentials.

    androidx.credentials:credentials:1.6.0
    androidx.credentials:credentials-play-services-auth:1.6.0
    

Встроенные методы аутентификации

Поскольку Менеджер учетных данных – это единый API, инструкции по его реализации для Wear OS такие же, как и для других типов устройств.

Чтобы начать работу и реализовать поддержку ключей доступа и паролей, следуйте инструкциям для мобильных устройств.

Инструкции по добавлению поддержки входа с аккаунтом Google в Менеджер учетных данных предназначены для разработчиков мобильных приложений, но они также подходят для Wear OS.

Обратите внимание, что на устройствах Wear OS нельзя создавать учетные данные, поэтому вам не нужно реализовывать методы создания учетных данных, упомянутые в инструкциях для мобильных устройств.

Резервные способы аутентификации

Для приложений Wear OS также допустимы два других метода аутентификации: OAuth 2.0 (любой вариант) и передача токена аутентификации с мобильного устройства через уровень данных. Эти методы не имеют точек интеграции в Credential Manager API, но их можно включить в UX-поток Credential Manager в качестве резервных вариантов на случай, если пользователи закроют экран Credential Manager.

Чтобы обработать действие пользователя по закрытию экрана Менеджера учетных данных, перехватите NoCredentialException как часть логики GetCredential и перейдите к собственному пользовательскому интерфейсу аутентификации.

try {
    val getCredentialResponse: GetCredentialResponse =
        credentialManager.getCredential(activity, createGetCredentialRequest())
    return authenticate(getCredentialResponse.credential)
} catch (_: GetCredentialCancellationException) {
    navigateToSecondaryAuthentication()
}

Затем в пользовательском интерфейсе аутентификации можно будет использовать любой другой допустимый способ аутентификации, описанный в руководстве по UX для входа в аккаунт.

Передача токенов уровня данных

Сопутствующее приложение для телефона может безопасно передавать данные аутентификации в приложение Wear OS с помощью Wearable Data Layer API. Передавать учетные данные в виде сообщений или объектов данных.

Обычно этот тип аутентификации не требует никаких действий от пользователя. Однако не выполняйте аутентификацию без уведомления пользователя о том, что он входит в аккаунт. Вы можете сообщить пользователю о том, что его аккаунт переносится с мобильного устройства, с помощью закрываемого экрана.

Важно! В приложении для Wear OS должен быть хотя бы один другой способ аутентификации, поскольку этот вариант работает только на часах, подключенных к устройству Android, при условии, что на нем установлено соответствующее мобильное приложение. Предоставьте альтернативный способ аутентификации для пользователей, у которых нет соответствующего мобильного приложения или чье устройство Wear OS подключено к устройству iOS.

Передавайте токены с помощью уровня данных из мобильного приложения, как показано в следующем примере:

val token = "..." // Auth token to transmit to the Wear OS device.
val putDataReq: PutDataRequest = PutDataMapRequest.create("/auth").run {
    dataMap.putString("token", token)
    asPutDataRequest()
}
val putDataTask: Task<DataItem> = Wearable.getDataClient(this).putDataItem(putDataReq)

Прослушивайте события изменения данных в приложении для Wear OS, как показано в следующем примере:

class AuthDataListenerService : WearableListenerService() {
    override fun onDataChanged(dataEvents: DataEventBuffer) {
        dataEvents.forEach { event ->
            if (event.type == DataEvent.TYPE_CHANGED) {
                val dataItemPath = event.dataItem.uri.path ?: ""

                if (dataItemPath.startsWith("/auth")) {
                    val token = DataMapItem.fromDataItem(event.dataItem)
                        .dataMap
                        .getString("token")
                    // Display an interstitial screen to notify the user that they're being signed
                    // in. Then, store the token and use it in network requests.
                    handleSignInSequence(token)
                }
            }
        }
    }

    /** placeholder sign in handler. */
    fun handleSignInSequence(token: String?) {}
}

Подробнее о том, как отправлять и синхронизировать данные на устройствах Wear OS…

Как использовать OAuth 2.0

Wear OS поддерживает два потока на основе OAuth 2.0, которые описаны в следующих разделах:

  • Предоставление кода авторизации с PKCE (Proof Key for Code Exchange), как определено в RFC 7636.
  • Тип разрешения "Авторизация устройства" (DAG), как определено в RFC 8628.
Proof Key for Code Exchange (PKCE)

Чтобы эффективно использовать PKCE, применяйте RemoteAuthClient. Чтобы выполнить запрос авторизации из приложения для Wear OS к поставщику OAuth, создайте объект OAuthRequest. Этот объект состоит из URL конечной точки OAuth для получения токена и объекта CodeChallenge.

В примере ниже показано, как создать запрос на авторизацию:

val oauthRequest = OAuthRequest.Builder(context)
    .setAuthProviderUrl(uri)
    .setCodeChallenge(codeChallenge)
    .setClientId(CLIENT_ID)
    .build()

После того как вы создадите запрос на авторизацию, отправьте его в сопутствующее приложение с помощью метода sendAuthorizationRequest():

RemoteAuthClient.create(context).sendAuthorizationRequest(
    request = oauthRequest,
    executor = { command -> command?.run() },
    clientCallback = object : RemoteAuthClient.Callback() {
        override fun onAuthorizationResponse(
            request: OAuthRequest,
            response: OAuthResponse
        ) {
            // Extract the token from the response, store it, and use it in requests.
            continuation.resume(parseCodeFromResponse(response))
        }
        override fun onAuthorizationError(request: OAuthRequest, errorCode: Int) {
            // Handle Errors
            continuation.resume(Result.failure(IOException("Authorization failed")))
        }
    }
)

Этот запрос вызывает обращение к приложению-компаньону, которое затем показывает интерфейс авторизации в веб-браузере на мобильном телефоне пользователя. Поставщик OAuth 2.0 аутентифицирует пользователя и получает его согласие на запрошенные разрешения. Ответ отправляется на автоматически сгенерированный URL переадресации.

После успешной или неудачной авторизации сервер OAuth 2.0 перенаправляет на URL, указанный в запросе. Если пользователь одобрит запрос доступа, ответ будет содержать код авторизации. Если пользователь не одобрит запрос, в ответе будет сообщение об ошибке.

Ответ представляет собой строку запроса и выглядит примерно так:

  https://wear.googleapis.com/3p_auth/com.your.package.name?code=xyz
  https://wear.googleapis-cn.com/3p_auth/com.your.package.name?code=xyz

Загрузится страница, на которой пользователю будет предложено перейти в приложение-компаньон. Оно проверит URL ответа и передаст ответ в ваше приложение для Wear OS с помощью API onAuthorizationResponse.

Затем приложение для часов может обменять код авторизации на токен доступа.

Предоставление авторизации устройства

При использовании Device Authorization Grant пользователь открывает URI для подтверждения на другом устройстве. Затем сервер авторизации попросит их одобрить или отклонить запрос.

Чтобы упростить этот процесс, используйте RemoteActivityHelper, чтобы открыть веб-страницу на подключенном мобильном устройстве пользователя, как показано в следующем примере:

// Request access from the authorization server and receive Device Authorization Response.
private fun verifyDeviceAuthGrant(verificationUri: String) {
    RemoteActivityHelper(context).startRemoteActivity(
        Intent(Intent.ACTION_VIEW).apply {
            addCategory(Intent.CATEGORY_BROWSABLE)
            data = Uri.parse(verificationUri)
        },
        null
    )
}

Если у вас есть приложение для iOS, используйте универсальные ссылки, чтобы перехватывать это намерение в приложении, а не полагаться на браузер для авторизации токена.