Flusso di Verifica Email con Deep Link
Questo documento spiega come funziona la verifica email in-app tramite deep link per iOS e Android.
Panoramica
Quando un utente si registra, riceve un'email con un link di verifica. Invece di aprire una pagina web, il link apre direttamente l'app che verifica il token tramite API.
Formati dei Link
Universal Links (HTTPS)
https://app.vislagps.com/verify?token=abc123
Custom Scheme (Fallback)
vislagps://verify?token=abc123
Implementazione iOS
File di Configurazione
| File | Scopo |
|---|---|
Info.plist | Registra lo scheme custom vislagps:// |
VislaGPS.entitlements | Configura applinks:app.vislagps.com |
apple-app-site-association | Lato server: mappa /verify* all'app |
Flusso del Codice
-
Ingresso Deep Link —
VislaGPSApp.swift.onOpenURL { url in
handleDeepLink(url)
} -
Estrazione Token —
handleDeepLink()if url.path.contains("verify") || url.host == "verify" {
let token = components.queryItems?.first(where: { $0.name == "token" })?.value
verifyEmailToken(token)
} -
Chiamata API —
ApiClient.verifyEmail()POST /api/auth/verify
Body: { "token": "abc123" } -
Risultato — Mostra alert di successo/errore
Implementazione Android
File di Configurazione
| File | Scopo |
|---|---|
AndroidManifest.xml | Intent filter per i deep link |
assetlinks.json | Lato server: verifica dell'app |
Intent Filters
<!-- Universal Links -->
<intent-filter android:autoVerify="true">
<data android:scheme="https"
android:host="app.vislagps.com"
android:pathPrefix="/verify" />
</intent-filter>
<!-- Custom Scheme -->
<intent-filter>
<data android:scheme="vislagps"
android:host="verify" />
</intent-filter>
Flusso del Codice
-
Ingresso Deep Link —
MainActivity.ktoverride fun onCreate() { handleDeepLink(intent) }
override fun onNewIntent(intent: Intent) { handleDeepLink(intent) } -
Estrazione Token —
handleDeepLink()if (uri.path?.contains("verify") == true || uri.host == "verify") {
val token = uri.getQueryParameter("token")
verifyEmailToken(token)
} -
Chiamata API —
ApiClient.verifyEmail()POST /api/auth/verify
Body: { "token": "abc123" } -
Risultato — Mostra AlertDialog
Configurazione Server
apple-app-site-association
Percorso: services/web-app/public/.well-known/apple-app-site-association
{
"applinks": {
"details": [{
"appID": "JBVMSR9P49.com.visla.vislagps",
"paths": ["/app/*", "/verify*"]
}]
}
}
assetlinks.json
Percorso: services/web-app/public/.well-known/assetlinks.json
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.visla.vislagps",
"sha256_cert_fingerprints": ["67:B2:F4:..."]
}
}]
API Backend
POST /api/auth/verify
Richiesta:
{ "token": "token-di-verifica-dalla-email" }
Risposta (200):
{ "message": "Email verified successfully" }
Risposta (400):
{ "detail": "Invalid or expired token" }
Test
iOS Simulator
xcrun simctl openurl booted "vislagps://verify?token=test123"
Android Emulator
adb shell am start -a android.intent.action.VIEW -d "vislagps://verify?token=test123"
Universal Link (entrambe le piattaforme)
# Richiede server configurato correttamente
https://app.vislagps.com/verify?token=test123
Social Login (Google, Apple, Facebook)
Flusso OAuth
- Utente clicca bottone social nella schermata login
- App apre browser:
GET /api/auth/openid/auth?provider=google&ret=app - Backend redirect a provider (Google/Apple/Facebook)
- Utente autorizza
- Provider redirect a callback backend
- Backend genera token e redirect:
com.visla.vislagps://oauthredirect?access_token=xxx - App riceve deep link, salva token, login completato
Configurazione Backend
# Nel .env o docker-compose
OPENID_GOOGLE_ENABLED=true
OPENID_GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
OPENID_APPLE_ENABLED=true
OPENID_APPLE_CLIENT_ID=com.visla.vislagps
OPENID_APPLE_TEAM_ID=JBVMSR9P49
OPENID_APPLE_KEY_ID=xxx
OPENID_FACEBOOK_ENABLED=true
OPENID_FACEBOOK_CLIENT_ID=xxx
Test Social Login
# iOS Simulator
xcrun simctl openurl booted "com.visla.vislagps://oauthredirect?access_token=test123"
# Android Emulator
adb shell am start -a android.intent.action.VIEW -d "com.visla.vislagps://oauthredirect?access_token=test123"