В этом руководстве подробно описано, как использовать API DigitalCredential для получения подтвержденных телефонных номеров ваших пользователей. Процесс состоит из двух шагов:
- Запрос
TS.43 token: Ваше клиентское приложение («верификатор») запрашивает временный токен TS.43 с устройства пользователя.TS.43 token— это выданные оператором связи учетные данные, представляющие личность пользователя. - Обмен токена на номер телефона : бэкэнд вашего приложения обменивает
TS.43 tokenу агрегатора или оператора связи на подтвержденный номер телефона пользователя.
совместимость с версиями Android
API проверки номера телефона поддерживается на Android 10 (уровень API 29) и выше.
Предварительные требования
Для реализации проверки номера телефона с помощью API DigitalCredential вам потребуется учетная запись у агрегатора. Агрегатор взаимодействует с операторами связи и предоставляет необходимую API-инфраструктуру для вашего приложения, обычно в виде платной облачной API-терминалы.
Также необходимо добавить следующие зависимости в скрипт сборки Gradle:
Котлин
dependencies { implementation("androidx.credentials:credentials:1.6.0-rc02") implementation("androidx.credentials:credentials-play-services-auth:1.6.0-rc02") }
Круто
dependencies { implementation "androidx.credentials:credentials:1.6.0-rc02" implementation "androidx.credentials:credentials-play-services-auth:1.6.0-rc02" }
Выполнение
Весь процесс от начала до конца обычно включает следующие этапы:
- Запрос параметров DCQL (Digital Credential Query Language) у агрегатора : обратитесь к одному или нескольким агрегаторам и запросите набор параметров DCQL. DCQL позволяет указать точные цифровые учетные данные, которые вам необходимы от каждого агрегатора.
Создайте запрос OpenID4VP : В бэкэнде вашего приложения создайте запрос OpenID4VP, включив в него параметры DCQL от агрегатора. Затем отправьте запрос OpenID4VP в ваше клиентское приложение.
Вызов API диспетчера учетных данных : В вашем клиентском приложении используйте API диспетчера учетных данных для отправки запроса OpenID4VP в операционную систему. В ответ вы получите объект ответа OpenID4VP, содержащий
TS.43 Digital Credential. Эти учетные данные зашифрованы и могут быть расшифрованы только соответствующим агрегатором. После получения токена оператора связи отправьте ответ из вашего клиентского приложения на бэкэнд приложения.Проверьте ответ : В бэкэнде вашего приложения проверьте ответ OpenID4VP.
Обмен на номер телефона : из бэкэнда вашего приложения отправьте
TS.43 Digital Credentialагрегатору. Агрегатор проверит учетные данные и вернет подтвержденный номер телефона.
Запрос параметров DCQL у агрегатора
Из бэкэнда вашего приложения отправьте запрос агрегатору для получения объекта учетных данных в формате DCQL (Digital Credential Query Language). Убедитесь, что в запросе указаны nonce и идентификатор запроса. Агрегатор вернет объект учетных данных DCQL, структура которого выглядит примерно так:
{
// The credential ID is mapped to the request ID that is sent in your request to the aggregator.
"id": "aggregator1",
"format": "dc-authorization+sd-jwt",
"meta": {
"vct_values": [
"number-verification/device-phone-number/ts43"
],
"credential_authorization_jwt": "..."
},
"claims": [
{
"path": ["subscription_hint"],
"values": [1]
},
{
"path": ["phone_number_hint"],
"values": ["+14155552671"]
}
]
}
Создайте запрос OpenID4VP
Во-первых, в бэкэнде вашего приложения создайте объект dcql_query , поместив объект учетных данных DCQL в массив credentials , вложенный в объект dcql_query , как показано в следующем примере:
"dcql_query": {
"credentials": [
"id": "aggregator1",
"format": "dc-authorization+sd-jwt",
"meta": {
"vct_values": [
"number-verification/device-phone-number/ts43"
],
"credential_authorization_jwt": "..."
},
"claims": [
{
"path": ["subscription_hint"],
"values": [1]
},
{
"path": ["phone_number_hint"],
"values": ["+14155552671"]
}
]
]
}
Затем создайте запрос OpenID4VP со следующей структурой:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
-
protocol: Для запросов на подтверждение номера телефона необходимо установить значениеopenid4vp-v1-unsigned. -
response_typeиresponse_mode: Константы, обозначающие формат запроса, с фиксированными значениямиvp_tokenиdc_apiсоответственно. -
nonce: Уникальное значение, генерируемое вашим бэкэндом для каждого запроса. Значение nonce в объекте учетных данных DCQL агрегатора должно совпадать с этим значением nonce. -
dcql_query: В данном случае используйтеdcql_query, чтобы указать, что запрашиваютсяTS.43 Digital Credential. Здесь также можно запросить другие цифровые учетные данные.
Затем оберните запрос OpenID4VP в объект запроса API DigitalCredential и отправьте его в клиентское приложение.
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
]
}
Следующий фрагмент кода демонстрирует, как сгенерировать запрос к API DigitalCredential:
def GenerateDCRequest():
credentials = []
aggregator1_dcql = call_aggregator_endpoint(nonce, "aggregator1", additional_params)
credentials.append(aggregator1_dcql) # You can optionally work with multiple
# aggregators, or request other types of credentials
val dc_request =
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": {"credentials": credentials}
}
}
]
}
return dc_request
Вызовите API диспетчера учетных данных.
В клиентском приложении выполните вызов API менеджера учетных данных, используя запрос к API DigitalCredential, предоставленный бэкэндом вашего приложения.
val requestJson = generateTs43DigitalCredentialRequestFromServer()
val digiCredOption = GetDigitalCredentialOption(requestJson = requestJson)
val getCredRequest = GetCredentialRequest(
listOf(digiCredOption)
)
coroutineScope.launch {
try {
val response = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
val credential = response.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson)
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential ${credential.type}")
}
}
} catch (e : GetCredentialException) {
// If user cancels the operation, the feature isn't available, or the
// SIM doesn't support the feature, a GetCredentialCancellationException
// will be returned. Otherwise, a GetCredentialUnsupportedException will
// be returned with details in the exception message.
handleFailure(e)
}
}
Ответ API DigitalCredential содержит ответ OpenID4VP. Типичный JSON-файл учетных данных из результата DigitalCredential выглядит следующим образом:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"vp_token": {
"aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
# Credential in an array structure.
}
}
}
Из клиентского приложения отправьте ответ API DigitalCredential обратно на бэкэнд-сервер, где он будет проверен и использован для обмена на подтвержденный номер телефона с агрегатором.
Проверьте ответ, полученный с помощью цифровых учетных данных.
Ниже приведён пример того, как обработать ответ и выполнить проверку в бэкэнде вашего приложения:
def processDigitalCredentialsResponse(response):
# Step 1: Parse out the TS.43 Digital Credential from the response
openId4VpResponse = response['data']
ts43_digital_credential = response['vp_token']["aggregator1"][0]
# Step 2: Perform response validation
verifyResponse(ts43_digital_credential)
def verifyResponse(ts43_digital_credential):
# The returned ts43_digital_credential is an SD-JWT-based Verifiable Credentials
# (SD-JWT VC) as defined in this IETF spec. The section 3.4 of the specification
# outlines how to validate the credential. At a high level, the steps involves
# validating (1) the nonce in the response credential matches the one in the
# request, (2) the integrity of the credential by checking the credential is
# signed by the trusted issuer Android Telephony, and (3) other validity
# properties associated with this credential, such as issue time and expiration
# time
# In most cases, you can use an SD-JWT VC library to perform these validations.
# Some aggregators may also perform the validation logic for you. Check with your
# aggregator to decide the exact scope of the validation required.
Обмен на номер телефона
Из бэкэнда вашего приложения отправьте проверенные TS.43 Digital Credential на конечную точку агрегатора для проверки учетных данных и получения подтвержденного номера телефона.
def processDigitalCredentialsResponse(response):
# ... prior steps
# Step 3: Call aggregator endpoint to exchange the verified phone number
callAggregatorPnvEndpoint(ts43_digital_credential)