Verbindung mit dem Backend
Integration der Benutzeroberfläche mit den Backend-Endpunkten
Im vorigen Modul haben wir die Benutzeroberfläche und eine kleine UI-Zustandsmaschine (VerifyUiState). Jetzt verbinden wir diese Benutzeroberfläche mit unserem Backend.
Der Grundgedanke ist, dass die Android-App niemals Vonage direkt anruft. Sie wird nur Ihr Backend anrufen:
POST /verificationum den Prüfablauf zu startenPOST /check-codeum einen Code zu validieren (vorerst SMS-Code)POST /nextden Fallback-Kanal (SMS) sofort zu erzwingen (damit wir nicht ~20 Sekunden warten müssen)
Beginnen wir mit der Umsetzung!
Überprüfung starten (POST /verification)
Wenn der Benutzer tippt Überprüfung starten:
Die App sendet die Rufnummer an
/verificationDas Backend gibt zurück:
request_id(immer)check_url(optional, wird später für Silent Auth verwendet)
In diesem Abschnitt wird Silent Auth übersprungen und sofort ein Fallback zu SMS durch den Aufruf von
/nextDie Benutzeroberfläche wechselt zum SMS-Bildschirm (
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)
}
SMS-Code einreichen (POST /check-code)
Wenn der Benutzer tippt Code einreichen:
- Die App sendet
{ request_id, code }zu/check-code - Das Backend antwortet mit
{ verified: true/false } - UI zeigt Erfolg oder "ungültigen Code" an
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
)
}
Fallback schnell erzwingen (POST /next)
Aufruf von /next ist aus Sicht der "Korrektheit" optional (Vonage kann automatisch darauf zurückgreifen), aber es ist sehr nützlich für die Benutzerfreundlichkeit:
Wenn wir bereits wissen, dass wir Silent Auth nicht abschließen werden (oder wir es noch nicht implementiert haben), kann der Aufruf von /next vermeidet das Warten auf die Zeitüberschreitung von Silent Auth.
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")
}
}
Erste Schritte mit der stillen Authentifizierung
Silent Authentication ist nicht ganz einfach zu verstehen. Dieses Tutorial zeigt Ihnen, wie Sie eine Integration von Grund auf mit Nodejs und Kotlin erstellen können