Conecte-se ao backend
Integração da interface do usuário com os pontos de extremidade do backend
No módulo anterior, criamos a interface do usuário e uma pequena máquina de estados para a interface do usuário (VerifyUiState). Agora vamos conectar essa interface do usuário ao nosso backend.
A ideia principal é que o aplicativo para Android nunca entre em contato diretamente com a Vonage. Ele entrará em contato apenas com o seu backend:
-
POST /verificationpara iniciar o fluxo de verificação -
POST /check-codepara validar um código (código por SMS, por enquanto) -
POST /nextpara forçar o uso do canal alternativo (SMS) imediatamente (para não termos que esperar cerca de 20 segundos)
Vamos começar com a implementação!
Iniciar verificação (POST /verification)
Quando o usuário toca em Iniciar a verificação:
-
O aplicativo envia o número de telefone para
/verification -
O backend retorna:
request_id(sempre)check_url(opcional, usado posteriormente para a autenticação silenciosa)
-
Nesta seção, vamos ignorar a autenticação silenciosa e solicitar imediatamente o recurso alternativo por SMS chamando
/next -
A interface do usuário faz a transição para a tela de SMS (
EnterSms(requestId))
private suspend fun startVerification(phone: String): Pair<String, String?> = withContext(Dispatchers.IO) {
val client = OkHttpClient()
val json = Gson().toJson(mapOf("phone" to phone))
val requestBody = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("$BACKEND_URL/verification")
.post(requestBody)
.build()
val response = client.newCall(request).execute()
if (!response.isSuccessful) {
val errorBody = response.body?.string() ?: "Unknown error"
throw IOException("Start verification failed: HTTP ${response.code} - $errorBody")
}
val body = response.body?.string() ?: throw IOException("Empty response body")
val jsonBody = Gson().fromJson(body, JsonObject::class.java)
val requestId = jsonBody.get("request_id")?.asString ?: throw IOException("Missing request_id")
val checkUrl = jsonBody.get("check_url")?.asString // may be null
Pair(requestId, checkUrl)
}
Enviar código por SMS (POST /check-code)
Quando o usuário toca em Enviar código:
- O aplicativo envia
{ request_id, code }para/check-code - O backend responde com
{ verified: true/false } - A interface do usuário exibe “sucesso” ou “código inválido”
private suspend fun submitCode(requestId: String, code: String): CheckCodeResponse = withContext(Dispatchers.IO) {
val client = OkHttpClient()
val json = Gson().toJson(mapOf("request_id" to requestId, "code" to code))
val requestBody = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("$BACKEND_URL/check-code")
.post(requestBody)
.build()
val response = client.newCall(request).execute()
if (!response.isSuccessful) {
val errorBody = response.body?.string() ?: "Unknown error"
throw IOException("Check code failed: HTTP ${response.code} - $errorBody")
}
val body = response.body?.string() ?: throw IOException("Empty response body")
val jsonBody = Gson().fromJson(body, JsonObject::class.java)
CheckCodeResponse(
verified = jsonBody.get("verified")?.asBoolean ?: false,
status = jsonBody.get("status")?.asString
)
}
Forçar o fallback rapidamente (POST /next)
Chamando /next é opcional do ponto de vista da “precisão” (a Vonage pode recorrer automaticamente a uma alternativa), mas é muito útil para a experiência do usuário:
Se já sabemos que não vamos concluir a autenticação silenciosa (ou ainda não a estamos implementando), chamar /next evita a espera pelo tempo limite da autenticação silenciosa.
private suspend fun requestNextWorkflow(requestId: String): Unit = withContext(Dispatchers.IO) {
val client = OkHttpClient()
val json = Gson().toJson(mapOf("requestId" to requestId))
val requestBody = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("$BACKEND_URL/next")
.post(requestBody)
.build()
val response = client.newCall(request).execute()
if (!response.isSuccessful) {
val errorBody = response.body?.string() ?: "Unknown error"
throw IOException("Next workflow failed: HTTP ${response.code} - $errorBody")
}
}
Introdução à autenticação silenciosa
A autenticação silenciosa leva um bom tempo para ser compreendida. Este tutorial mostra como criar uma integração do zero usando Node.js e Kotlin