Basi della sicurezza
Perché i link email di Supabase reindirizzano a localhost:3000
Se Supabase reindirizza a localhost:3000, la Site URL non è mai stata cambiata o il tuo indirizzo manca in Redirect URLs. La soluzione, e il jolly da evitare.

In breve
- Un reindirizzamento di Supabase a localhost:3000 viene dalla Site URL della pagina URL Configuration. Un progetto parte con http://localhost:3000, e ogni link email ci ricade quando l'indirizzo che la tua app ha chiesto non è nella lista Redirect URLs.
- Chi ha premuto un link di registrazione di solito è già confermato. Supabase conferma l'account prima di mandarlo altrove, quindi può accedere sul tuo sito vero.
- Imposta la Site URL sul tuo indirizzo online e metti in lista gli indirizzi esatti che usi. Un jolly così ampio da coprire l'app di qualcun altro permette a un link costruito ad arte di mandare lì i tuoi utenti, già con l'accesso fatto.
Un nuovo utente si registra sulla tua app online, apre l'email di conferma e preme il pulsante. Il suo browser apre una pagina che dice "This site can't be reached" e "localhost refused to connect" (così in un Chrome in inglese), sopra un indirizzo che comincia così:
http://localhost:3000/#access_token=…&expires_at=…&expires_in=…&refresh_token=…&sb=&token_type=bearer&type=signup
Se la tua app usa il flusso PKCE, finisce invece con ?code=…. Hai costruito
l'app con Lovable, Bolt, v0, Cursor, Claude Code o Replit, in anteprima
funzionava benissimo, e l'accesso con password funziona ancora.
Un reindirizzamento di Supabase a localhost significa che Supabase Auth, la
parte di Supabase che fa accedere le persone, ha finito il suo lavoro e poi ha
mandato la persona alla Site URL del tuo progetto, che dice ancora
http://localhost:3000. Quell'indirizzo vuol dire "questo computer". Sul
computer del tuo utente lì non c'è niente. La soluzione sono due impostazioni
in una pagina della dashboard di Supabase.
Ecco la parte che le soluzioni rapide in rete sbagliano: il jolly che fa sparire questo messaggio con una riga è anche quello che permette al link di uno sconosciuto di mandare i tuoi utenti sulla sua pagina, già con l'accesso fatto. Le impostazioni qui sotto fanno funzionare i link e tengono chiusa quella porta.
Che cosa significa un reindirizzamento di Supabase a localhost?
Significa che Supabase ha mandato la persona all'indirizzo predefinito del tuo progetto, perché non ne ha accettato uno migliore.
Ogni email che Supabase invia per te, che sia una conferma di registrazione, un
magic link, un ripristino della password o un invito, porta prima
all'indirizzo del tuo progetto. La
guida ai modelli di email
di Supabase ne mostra la forma:
https://project-ref.supabase.co/auth/v1/verify?token=…&type=email&redirect_to=https://example.com/path.
Lì Supabase controlla il token e poi manda il browser a ciò che indica
redirect_to.
Pensalo come un cartello indicatore alla porta di Supabase. Ogni persona che
apre un link fa l'accesso alla porta e poi viene mandata avanti, con la chiave
in mano, lungo una delle frecce. Le frecce le metti tu. La Site URL è la
freccia che prendono tutti quando nessun'altra va bene, e in un progetto nuovo
punta a http://localhost:3000: l'officina dove l'app è stata costruita, che
sulla macchina di chiunque altro è una stanza vuota.
La
guida ai reindirizzamenti
di Supabase dice che la Site URL definisce il reindirizzamento predefinito
quando nel codice non c'è nessun redirectTo, ti chiede di cambiarla da
http://localhost:3000 al tuo indirizzo di produzione e definisce questa
impostazione fondamentale per le conferme via email e i ripristini della
password.
Perché Supabase ignora l'indirizzo che la mia app ha chiesto?
Perché quell'indirizzo non è nella tua lista Redirect URLs, e Supabase ripiega su un altro senza dirtelo.
La tua app può indicare dove le persone devono arrivare. Nella libreria
JavaScript di Supabase è emailRedirectTo su signUp e signInWithOtp, e
redirectTo su resetPasswordForEmail e signInWithOAuth. Poi Supabase Auth
decide in
una breve funzione,
in quest'ordine:
- L'indirizzo che la tua app ha chiesto, se corrisponde a una voce della tua lista Redirect URLs o sta sullo stesso dominio della tua Site URL.
- L'indirizzo della pagina da cui è partita la richiesta, come l'ha riportato il browser, con la stessa regola.
- Altrimenti la Site URL. Supabase non segnala nessun errore, e la console della tua app non mostra niente.
Prende questa decisione quando l'email viene inviata, e l'indirizzo scelto
finisce nel link. Quando qualcuno apre il link, Supabase ricontrolla
quell'indirizzo con le tue impostazioni così come sono in quel momento. La
stessa
risposta di risoluzione dei problemi
di Supabase riassume la regola in una frase: perché l'opzione redirectTo
funzioni, devi inserire l'URL esatto nell'impostazione Redirect URLs.
La stessa impostazione decide dove "Sign in with Google" riporta le persone, quindi un pulsante Google che atterra su localhost ha la stessa causa. Un pulsante Google che si ferma prima, su una pagina con scritto "Unsupported provider: provider is not enabled", è invece un interruttore in Supabase e una lista su Google.
Perché non l'hai visto prima del lancio
Perché i due modi in cui hai fatto le prove non arrivano mai alla Site URL.
- L'accesso con password avviene dentro la pagina. Niente link email e nessun passaggio dalla porta di Supabase, quindi il cartello non viene mai letto.
- Se costruisci con Cursor o Claude Code e il tuo server di sviluppo era acceso sulla porta 3000 quando hai provato l'email, il link ha aperto la tua copia locale e sembrava funzionare.
- Sul backend integrato di Lovable forse non ti capiterà mai. La
documentazione sull'autenticazione
di Lovable dice che imposta la Site URL sul tuo indirizzo
lovable.apppubblicato quando pubblichi, e che aggiunge un dominio personalizzato alle redirect URL quando lo colleghi. La stessa pagina dice che le app che usano il tuo progetto Supabase non ricevono aggiornamenti automatici.
L'account è confermato anche se la pagina non si è caricata?
Sì, per una conferma di registrazione. Supabase conferma prima e manda avanti il browser solo dopo.
Nel codice che gestisce il link, l'account viene confermato prima che parta il reindirizzamento. La pagina che non si carica arriva a lavoro già fatto. Quindi di' alla persona che può accedere sul tuo sito online con la password che ha scelto. Premere di nuovo la stessa email non serve: il link funziona una volta, e la seconda pressione risponde "Email link is invalid or has expired".
Un magic link o un ripristino della password è diverso. Quell'accesso è finito su localhost ed è rimasto lì, quindi quando avrai corretto le impostazioni la persona avrà bisogno di una nuova email.
Come correggere il reindirizzamento di Supabase a localhost
Cambia la Site URL, poi metti in lista gli altri indirizzi a cui mandi le persone. Entrambi stanno nella pagina URL Configuration, sotto Authentication, nella dashboard di Supabase.
Imposta la Site URL sul tuo indirizzo online, con https:// davanti.https://yourapp.com, scritto per intero. Senza https://, Supabase lo legge
come un percorso sul proprio indirizzo, e la persona finisce invece sul tuo
progetto Supabase con
"No API key found in request". Da lì in
poi qualsiasi indirizzo di quel dominio viene accettato a qualsiasi percorso
senza voce in lista, quindi https://yourapp.com/welcome funziona appena la
Site URL è giusta.
Aggiungi gli altri indirizzi a Redirect URLs. La versione con www se le
persone la usano, l'indirizzo pubblicato sul builder
(https://yourapp.lovable.app, per esempio) se le persone si registrano lì, e
nient'altro. Una voce è uno schema, quindi https://yourapp.com/** copre ogni
pagina di quell'unico dominio.
Controlla che cosa chiede il tuo codice. Se passa window.location.origin,
l'indirizzo è quello su cui è stata aperta la pagina, e ogni indirizzo che ne
può uscire deve stare sul dominio della tua Site URL o nella lista.
Confrontali lettera per lettera: con www o senza, con https o senza. Una
voce senza /** in fondo corrisponde a quell'indirizzo esatto e a niente al di
sotto.
Controlla i tuoi modelli di email. Un modello che costruisce il proprio
link con {{ .SiteURL }} manda tutti alla Site URL, qualunque cosa abbia
chiesto la tua app. La guida ai reindirizzamenti di Supabase dice che, usando
l'opzione redirectTo, potresti dover sostituire {{ .SiteURL }} con
{{ .RedirectTo }} nei tuoi modelli di email.
| Cosa vedi | Cosa cambiare |
|---|---|
Ogni link apre localhost:3000 | La Site URL |
| I link aprono la tua Site URL invece dell'indirizzo che il tuo codice ha chiesto | Aggiungi quell'indirizzo a Redirect URLs, lettera per lettera |
| Il dominio online funziona e l'indirizzo pubblicato sul builder no | Aggiungi l'indirizzo pubblicato a Redirect URLs |
| Un link apre il tuo indirizzo Supabase con "No API key found in request" | Aggiungi https:// alla Site URL |
| L'indirizzo che la tua app chiede è in lista e il link lo ignora lo stesso | Il {{ .SiteURL }} nel modello di email |
Poi registrati di nuovo con un indirizzo che non hai ancora usato. Un'email
inviata prima della correzione con il link standard di Supabase, e aperta entro
la sua ora, ora arriva sul tuo sito online, perché Supabase ricontrolla
l'indirizzo quando il link viene aperto. Vale a meno che
http://localhost:3000 sia ancora nella tua lista.
Quali Redirect URLs si possono consentire senza rischi?
Gli indirizzi esatti che sono tuoi. Un jolly va bene per i deploy di anteprima, e solo limitato al tuo team o progetto.
La guida ai reindirizzamenti di Supabase lo dice chiaramente: il "globstar"
(**) è utile per lo sviluppo locale e gli indirizzi di anteprima, ma in
produzione consiglia di fissare il percorso di reindirizzamento esatto della tua
Site URL.
Il motivo è ciò che viaggia con la persona. Nel flusso predefinito, Supabase
scrive la nuova sessione nell'indirizzo a cui la manda:
il codice che lo costruisce
aggiunge #access_token=…&refresh_token=… all'indirizzo di reindirizzamento.
Qualsiasi pagina a quell'indirizzo può leggere quei due valori, e con quelli è
quell'utente. Sul cartello, è la freccia a decidere chi riceve la chiave.
Quindi una voce che copre un indirizzo controllato da qualcun altro è una via d'accesso agli account dei tuoi utenti. Chiunque può chiedere al tuo progetto di mandare via email a uno dei tuoi utenti un link di accesso, usando la chiave pubblica che sta nella tua app per scelta, e indicare la propria pagina come destinazione. L'email che arriva viene davvero dalla tua app. Il flusso PKCE non cambia le cose, perché chi ha scritto quel link ha avviato l'accesso, e PKCE consegna la sessione a chi l'ha avviato.
Gli schemi che coprono indirizzi che altri possono creare:
**da solo copre ogni indirizzo esistente.https://*.vercel.app/**copre ogni deploy di Vercel su internet, e chiunque può crearne uno. L'esempio di Supabase stesso contiene il tuo team:https://*-<team-or-account-slug>.vercel.app/**.https://*.lovable.app/**,https://*.netlify.app/**e la stessa forma sul dominio di qualsiasi builder fanno lo stesso per quel builder. Anche l'esempio di Supabase per Netlify è limitato:https://**--my_org.netlify.app/**.
Se hai appena risolto incollando un jolly, ricontrolla la lista oggi stesso.
Il lancio è anche il momento in cui si guardano le altre impostazioni che contano solo in produzione. La nostra scansione gratuita legge la tua app online dall'esterno e segnala ciò che uno sconosciuto può raggiungere: tabelle che rispondono a chiunque, chiavi segrete nel codice che la tua app invia, header mancanti, il certificato. Ci vogliono circa 20 secondi e non serve un account: scansiona la tua app.
Tenere d'occhio l'app online dopo il lancio
Questa impostazione si corregge una volta. Quello che la tua app invia ai visitatori cambia a ogni deploy, e quella parte si può sorvegliare dall'esterno.
Reeve Monitor continua a controllare la tua app online:
- se risponde, ogni 60 secondi, così "il link non funziona" si distingue da "il sito è giù"
- tutti e nove i controlli ogni ora, su un massimo di tre app, comprese le chiavi segrete nel codice che la tua app invia ai visitatori
- un messaggio quando un risultato cambia, così un problema uscito con un deploy successivo ti raggiunge senza che tu debba andare a guardare
- un report mensile, in linguaggio semplice, di quello che ha visto
Reeve Care tiene una copia del tuo database Supabase, account compresi:
- una copia cifrata secondo una pianificazione, sullo spazio di archiviazione di Reeve nell'UE, fuori dal tuo account Supabase
- lo schema auth in cui vivono gli account dei tuoi utenti, così tornano insieme a tutto il resto
- ogni copia verificata prima che conti, contando le righe di ogni tabella
- anche i tuoi file caricati, appena colleghi una credenziale di Storage
- un ripristino in un clic, con una copia di sicurezza dello stato attuale presa prima
- tutto quello che fa Monitor
Cosa fare adesso
Cosa fare
- Imposta la Site URL nella pagina URL Configuration sul tuo indirizzo online,
https://compreso. - Aggiungi a Redirect URLs gli altri indirizzi esatti a cui mandi le persone, come la versione con
wwwe l'indirizzo pubblicato sul builder. - Assicurati che ogni indirizzo che il tuo codice passa come
emailRedirectTooredirectTosia in lista, e usa{{ .RedirectTo }}nei modelli che devono seguirlo. - Di' a chi ha visto la pagina di localhost dopo la registrazione che il suo account è confermato. I magic link e i ripristini della password richiedono una nuova email.
- Limita i jolly alle anteprime del tuo team, e non consentire mai tutte le app del dominio di un builder.
Se le persone premono il nuovo link e si sentono dire che è scaduto, quel messaggio ha una pagina tutta sua. La checklist di sicurezza in 10 minuti copre ciò che di solito resta aperto in un'app appena lanciata.
FAQ
Perché la mia email di conferma di Supabase apre localhost:3000?
Perché Supabase ha mandato la persona alla Site URL del tuo progetto, e la Site URL è ancora http://localhost:3000. Supabase la usa ogni volta che l'indirizzo chiesto dalla tua app manca dalla lista Redirect URLs, o quando la tua app non ne ha chiesto nessuno. Cambiala nella pagina URL Configuration, sotto Authentication.
L'account è confermato se il link ha aperto localhost?
Sì, per una conferma di registrazione. Supabase conferma prima l'indirizzo e solo dopo manda avanti il browser, quindi la pagina che fallisce arriva a lavoro già fatto. La persona può accedere sul tuo sito online con la password che ha scelto. Un magic link o un ripristino della password va inviato di nuovo.
Ho aggiunto il mio sito a Redirect URLs e va ancora su localhost. Perché?
La voce deve corrispondere lettera per lettera all'indirizzo offerto a Supabase: con www o senza, con https o senza, e il percorso, perché una voce senza /** in fondo corrisponde solo a quell'indirizzo preciso. Se corrispondono e il link la ignora ancora, il tuo modello di email costruisce il link con {{ .SiteURL }}. E correggi la Site URL stessa, perché è lì che ricade tutto il resto.
Devo aggiungere la mia Site URL alla lista Redirect URLs?
No. Supabase accetta qualsiasi indirizzo sul dominio stesso della Site URL senza voce in lista, a qualsiasi percorso. La lista serve per gli altri indirizzi: una versione con www, l'indirizzo pubblicato sul builder, i deploy di anteprima.
Posso usare un jolly nelle Redirect URLs di Supabase?
Per le anteprime, limitato al tuo team o progetto, come negli esempi di Supabase. Mai uno che copra indirizzi che altri possono creare, come tutte le app su vercel.app o lovable.app. Supabase consiglia l'indirizzo esatto del tuo sito in produzione.