Blog
Feature
6 febbraio 20269 min

Autenticazione con codice QR: il pattern WhatsApp Web con Supabase

Per connettere il sito web all'app mobile, volevo qualcosa di istantaneo. Nessun modulo, nessuna password da ridigitare. Il modello WhatsApp Web: scansiona un codice QR e boom, connesso. Ecco come ho implementato questo sistema in TAMSIV con Supabase Realtime, un fallback polling e un'UX che impressiona.

Punti chiave da ricordare:
- Il codice QR codifica un UUID di sessione unico — il sito si abbona in tempo reale tramite Supabase Realtime.
- Un fallback polling HTTP (ogni 2s) subentra se Realtime fallisce dopo 3 secondi.
- Il codice QR scade dopo 5 minuti e si rigenera automaticamente a 4min30 con un conto alla rovescia visivo.
- L'intero sistema è composto da 300 righe lato web e 150 lato mobile.

Perché scegliere l'autenticazione tramite codice QR piuttosto che un modulo classico?

L'autenticazione classica — email + password — funziona. Ma crea attrito. L'utente ha già un account sull'app mobile. Chiedergli di ridigitare le sue credenziali sul web significa costringerlo a ricordare una password, potenzialmente cercarla nel suo gestore, e rischiare un fallimento.

Il codice QR elimina questo attrito. L'utente è già autenticato sul suo telefono. Scansionare un codice richiede 2 secondi. Questo è il modello reso popolare da WhatsApp Web, Telegram e Discord. Gli utenti lo conoscono e se lo aspettano.

Per TAMSIV, è ancora più pertinente in quanto il sito web serve da complemento all'app mobile — non da sostituzione. Il codice QR materializza questo legame tra le due piattaforme.

Persona che scansiona un codice QR visualizzato su uno schermo di laptop con il suo smartphone per connettersi
Scansionare un codice QR richiede 2 secondi — contro 30 secondi per un modulo email/password.

Come funziona il flusso di autenticazione tramite codice QR?

Dal punto di vista dell'utente, è magia: scansiono, sono connesso. Dal punto di vista tecnico, è un balletto preciso di token e canali in tempo reale. Ecco i passaggi:

  1. Generazione: l'utente apre tamsiv.com. Il sito genera un UUID di sessione unico e crea una voce in Supabase con lo stato "pending".
  2. Visualizzazione: il codice QR codifica questo UUID. Il sito si abbona al canale Supabase Realtime per questa sessione.
  3. Scansione: l'utente scansiona il codice QR con l'app mobile TAMSIV. L'app decodifica l'UUID.
  4. Conferma: l'app invia il suo JWT esistente + l'UUID al backend. Il backend verifica il JWT, genera un token di autenticazione web e aggiorna la sessione a "confirmed".
  5. Connessione: il sito riceve l'aggiornamento tramite Realtime, recupera il token e l'utente è connesso.

Questo flusso garantisce che solo un utente già autenticato sull'app mobile possa confermare la sessione. Il token generato per il web ha una durata di vita limitata ed è indipendente dal token mobile — le due sessioni sono separate.

Come Supabase Realtime permette la connessione istantanea?

Supabase Realtime è il componente che rende l'esperienza istantanea. Quando l'app mobile conferma la sessione, il cambiamento nel database viene rilevato dal canale Realtime e spinto verso il browser — in pochi millisecondi.

Tecnicamente, il sito si abbona a un canale specifico filtrando sull'UUID di sessione:

supabase.channel('qr-auth-SESSION_UUID')
  .on('postgres_changes', { event: 'UPDATE', filter: `id=eq.SESSION_UUID` }, callback)
  .subscribe()

Il callback viene attivato non appena lo stato passa da "pending" a "confirmed". Il token di autenticazione è incluso nell'aggiornamento. L'utente vede la pagina di login trasformarsi in dashboard — senza alcuna azione aggiuntiva.

È lo stesso meccanismo Realtime che utilizzo per la cache di contenuto e gli aggiornamenti in diretta nei gruppi collaborativi.

Diagramma architettonico che mostra il flusso di autenticazione in tempo reale tra un'app mobile e un browser web
Il flusso completo: generazione del QR, scansione mobile, conferma tramite JWT, connessione web tramite Realtime.

Perché un fallback polling è indispensabile?

Supabase Realtime funziona molto bene nella maggior parte dei casi. Ma "la maggior parte" non è sufficiente per una funzionalità di autenticazione. Alcune reti aziendali bloccano i WebSockets. Alcuni proxy li interrompono. Alcuni browser hanno bug specifici.

Ho implementato un fallback polling HTTP che subentra automaticamente:

  • Il sito tenta la connessione Realtime per 3 secondi
  • Se la connessione fallisce, passa silenziosamente a un polling HTTP ogni 2 secondi
  • Il polling interroga direttamente il database: "la sessione UUID è confermata?"
  • L'utente non sa mai quale meccanismo viene utilizzato — l'esperienza è identica

Il ritardo di 3 secondi è un compromesso tra reattività e affidabilità. Più corto, si passerebbe troppo velocemente al polling (meno efficiente). Più lungo, l'utente attenderebbe senza feedback.

Questo modello duale (Realtime + polling) è una buona pratica per qualsiasi funzionalità critica. Non dipendere mai da un solo canale di comunicazione.

Come proteggere il sistema di codice QR?

L'autenticazione tramite codice QR introduce vettori di attacco specifici. Ecco le misure implementate in TAMSIV:

  • Scadenza a 5 minuti: un codice QR non utilizzato diventa invalido. Questo impedisce il riutilizzo di screenshot o di codici QR condivisi.
  • Uso unico: una sessione può essere confermata una sola volta. Qualsiasi tentativo successivo viene rifiutato.
  • Autenticazione richiesta lato mobile: solo un utente connesso all'app può confermare. Il JWT viene verificato lato backend come per i WebSockets.
  • Token effimero: il token generato per il web è a uso unico e a durata limitata. Serve solo per avviare la sessione web, non come token permanente.
  • UUID v4 imprevedibile: l'UUID utilizzato per la sessione è generato con un CSPRNG (Cryptographically Secure Pseudo-Random Number Generator). Impossibile da indovinare.

Queste misure sono allineate con le raccomandazioni OWASP per l'autenticazione.

Doppio schermo che mostra un conto alla rovescia su un browser web e un mirino di fotocamera che scansiona un codice QR su smartphone
Il codice QR si rigenera automaticamente a 4min30 con un conto alla rovescia visivo per guidare l'utente.

Qual è l'esperienza utente finale?

L'UX è stata curata nei minimi dettagli:

  1. Auto-rigenerazione del QR: a 4min30, il codice QR si rigenera automaticamente con un nuovo UUID. Un conto alla rovescia visivo indica il tempo rimanente. L'utente non deve mai aggiornare la pagina.
  2. Animazione di connessione: quando la scansione è confermata, un'animazione fluida transita tra la pagina di login e la dashboard. Nessun ricaricamento della pagina.
  3. Opzioni alternative: email/password e Magic Link sono disponibili sotto il codice QR. Nessun utente è bloccato se la scansione non funziona.
  4. Responsive: su mobile (quando il QR non ha senso), l'interfaccia privilegia email/password e Magic Link. Il QR è visualizzato solo su desktop/tablet.

Il sistema di onboarding guida i nuovi utenti web verso il codice QR per primi, con un fallback naturale verso i metodi classici.

Quanto codice rappresenta questa funzionalità?

Circa 300 righe lato web (componente QR, logica Realtime/polling, gestione dei token) e 150 righe lato mobile (scanner, verifica, chiamata API di conferma). È compatto.

La ragione: Supabase fa la maggior parte del lavoro. Il database memorizza le sessioni, Realtime spinge gli aggiornamenti, Auth gestisce i token. Il codice applicativo si concentra sull'orchestrazione e l'UX.

Questo è tipico dell'approccio architettura Supabase di TAMSIV: massimizzare ciò che la piattaforma offre nativamente, minimizzare il codice personalizzato. Lo stesso principio che guida la strategia di internazionalizzazione e il sistema di gamification.

Quali alternative al codice QR esistono per l'autenticazione cross-device?

Altri approcci sono possibili per l'autenticazione cross-device:

  • Deep links: inviare un link cliccabile all'utente che apre l'app e conferma. Funziona bene ma richiede che l'utente sia sullo stesso dispositivo — cosa che non è il caso qui.
  • Codice numerico: visualizzare un codice a 6 cifre che l'utente digita nell'app. Più universale ma più lento (6 secondi vs 2 secondi per una scansione).
  • Push notification: inviare una notifica push con un pulsante "Conferma". Richiede che le notifiche siano attivate e che il sistema FCM sia configurato.
  • WebAuthn/Passkeys: la soluzione moderna ma non ancora universalmente supportata su tutti i dispositivi.

Il codice QR offre il miglior compromesso tra rapidità, universalità e "effetto wow". È il tipo di funzionalità che fa dire "è ben pensato" — ed è esattamente l'impressione che TAMSIV vuole lasciare.

FAQ

Cosa succede se chiudo il browser dopo aver scansionato il codice QR?

Il token generato per la sessione web è memorizzato nel local storage. Alla prossima visita, il sito verifica questo token e ti riconnette automaticamente se il token è ancora valido. Non hai bisogno di scansionare nuovamente il codice QR ad ogni visita.

Si possono avere più sessioni web contemporaneamente?

Sì, ogni scansione crea una sessione indipendente. Puoi essere connesso sul tuo computer desktop e sul tuo laptop contemporaneamente. Ogni sessione ha il suo token e può essere revocata individualmente dalle impostazioni dell'app.

Il codice QR funziona senza connessione internet?

No, il codice QR richiede una connessione internet attiva da entrambi i lati (mobile e web). La scansione decodifica un UUID che deve essere verificato online tramite Supabase. Per un utilizzo offline, i metodi email/password rimangono disponibili.

Come TAMSIV protegge dal phishing tramite codice QR?

Il codice QR codifica solo un UUID di sessione — nessun dato sensibile. La conferma avviene tramite l'app ufficiale TAMSIV che verifica il dominio e la validità della sessione. Un codice QR contraffatto reindirizzerebbe a un UUID inesistente nel database e fallirebbe immediatamente.

Perché il codice QR scade dopo soli 5 minuti?

Cinque minuti è un compromesso sicurezza/UX. È abbastanza lungo perché l'utente abbia il tempo di prendere il telefono e scansionare. È abbastanza corto per limitare la finestra di attacco se il QR viene intercettato. La rigenerazione automatica a 4min30 garantisce un QR sempre fresco senza azione da parte dell'utente.