Este guia detalha como usar a API DigitalCredential para receber números de telefone verificados dos seus usuários. O processo envolve duas etapas:
- Solicitar um
TS.43 token
: o app cliente (o "verificador") solicita um token temporário TS.43 do dispositivo do usuário. OTS.43 token
é uma credencial emitida pela operadora que representa a identidade do usuário. - Troque o token por um número de telefone: o back-end do seu app troca o
TS.43 token
com um agregador ou uma operadora pelo número de telefone verificado do usuário.
Pré-requisitos
Para implementar a verificação de número de telefone com a API DigitalCredential, você precisa de uma conta com um agregador. Um agregador interage com as operadoras e fornece a superfície de API necessária para seu app, geralmente como um endpoint de API de nuvem faturável.
Você também precisa adicionar as seguintes dependências ao script de build do Gradle:
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.6.0-alpha05") implementation("androidx.credentials:credentials-play-services-auth:1.6.0-alpha05") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.6.0-alpha05" implementation "androidx.credentials:credentials-play-services-auth:1.6.0-alpha05" }
Implementação
O processo de ponta a ponta geralmente segue estas etapas:
- Solicitar parâmetros de DCQL (Digital Credential Query Language) de um agregador: chame um ou mais agregadores e solicite um conjunto de parâmetros de DCQL. Com a DCQL, é possível especificar as credenciais digitais exatas necessárias de cada agregador.
Crie a solicitação OpenID4VP: no back-end do app, crie a solicitação OpenID4VP e inclua os parâmetros de DCQL do agregador. Em seguida, envie a solicitação OpenID4VP para o app cliente.
Chame a API Credential Manager: no app cliente, use a API Credential Manager para enviar a solicitação OpenID4VP ao sistema operacional. Em resposta, você recebe um objeto de resposta OpenID4VP que contém o
TS.43 Digital Credential
. Essa credencial é criptografada e só pode ser descriptografada pelo agregador associado. Depois de receber o token da transportadora, envie a resposta do app cliente para o back-end do app.Valide a resposta: no back-end do app, valide a resposta OpenID4VP.
Trocar por número de telefone: no back-end do app, envie o
TS.43 Digital Credential
ao agregador. O agregador valida a credencial e retorna o número de telefone verificado.
Solicitar parâmetros de DCQL de um agregador
No back-end do app, envie uma solicitação ao agregador para um objeto de credencial da Digital Credential Query Language (DCQL). Forneça um uso único e um ID de solicitação na sua solicitação. O agregador retorna o objeto de credencial da DCQL, que tem uma estrutura semelhante a esta:
{
// 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"]
}
]
}
Criar a solicitação OpenID4VP
Primeiro, no back-end do app, crie um objeto dcql_query
colocando o objeto de credencial da DCQL
em uma matriz credentials
aninhada em um objeto dcql_query
conforme mostrado no exemplo a seguir:
"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"]
}
]
]
}
Em seguida, crie uma solicitação OpenID4VP com a seguinte estrutura:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
protocol
: precisa ser definido comoopenid4vp-v1-unsigned
para solicitações de verificação de número de telefone.response_type
eresponse_mode
: constantes que indicam o formato da solicitação com valores fixosvp_token
edc_api
, respectivamente.nonce
: um valor exclusivo gerado pelo seu back-end para cada solicitação. O nonce no objeto de credencial DCQL do agregador precisa corresponder a este nonce.dcql_query
: nesse caso, usedcql_query
para especificar que umTS.43 Digital Credential
está sendo solicitado. Você também pode solicitar outras credenciais digitais aqui.
Em seguida, encapsule a solicitação OpenID4VP em um objeto de solicitação da API DigitalCredential e envie para o app cliente.
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
]
}
O snippet a seguir demonstra como gerar a solicitação da 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
Chamar a API Credential Manager
No app cliente, faça uma chamada para a API Credential Manager com a solicitação da API DigitalCredential fornecida pelo back-end do app.
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)
}
}
A resposta da API DigitalCredential contém a resposta do OpenID4VP. Um JSON de credencial típico do resultado DigitalCredential
é assim:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"vp_token": {
"aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
# Credential in an array structure.
}
}
}
Do app cliente, envie a resposta da API DigitalCredential de volta para o servidor de back-end, onde ela pode ser validada e usada para trocar pelo número de telefone verificado com um agregador.
Validar a resposta da credencial digital
Confira um exemplo de como analisar a resposta e realizar a etapa de validação no back-end do app:
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.
Troca por número de telefone
No back-end do app, envie o TS.43 Digital Credential
validado para o endpoint do agregador, valide a credencial e receba o número de telefone verificado.
def processDigitalCredentialsResponse(response):
# ... prior steps
# Step 3: Call aggregator endpoint to exchange the verified phone number
callAggregatorPnvEndpoint(ts43_digital_credential)