
401 e 403 significano entrambi che non hai ricevuto la pagina, e vengono costantemente scambiati l’uno con l’altro, nei messaggi di errore e nei bug report. La differenza tra loro è piccola da leggere e grande da affrontare: uno riguarda chi sei, l’altro riguarda cosa ti è permesso fare.
Confondere l’uno con l’altro ti porta a risolvere il problema sbagliato. Quindi ecco la distinzione, cosa significa davvero ognuno, e come capire quale stai effettivamente guardando.
La versione a una riga
401 Unauthorized significa che il server non sa chi sei. Non sei autenticato, oppure le credenziali che hai inviato erano mancanti, sbagliate o scadute. Accedi correttamente e la richiesta avrebbe successo.
403 Forbidden significa che il server sa esattamente chi sei, e comunque non ti è permesso. Sei autenticato, le tue credenziali vanno bene, e questo account particolare semplicemente non è autorizzato a fare questa cosa particolare. Accedere di nuovo non cambia nulla, perché essere autenticato non è mai stato il problema.
In parole semplici: 401 è “non ti conosco”, 403 è “ti conosco, e no”.
La terminologia è un incidente storico che peggiora le cose. 401 è etichettato come “Unauthorized” quando in realtà significa non autenticato - il server non poteva stabilire chi sei. 403 è quello che riguarda effettivamente l’autorizzazione. I nomi sono bloccati per compatibilità, quindi leggi oltre di loro per capire cosa fa davvero ogni codice.
Come capire quale hai
Guarda se sei autenticato quando succede.
Se sei disconnesso, o la richiesta non conteneva alcun cookie di sessione o token, 401 è la risposta attesa e corretta, e la soluzione è autenticarsi. Se la stessa richiesta funziona una volta che accedi, è sempre stato solo 401.
Se sei autenticato - correttamente, con una sessione che il server accetta altrove - e un’azione o pagina specifica restituisce l’errore, stai guardando un 403. L’account è autenticato e la risposta è comunque no. Disconnettersi e accedere di nuovo, cancellare i cookie o provare un altro browser non cambierà nulla, e ognuno di questi è un comune mezzo’ora sprecato trattando un 403 come se fosse un 401.
Una trappola degna di nota: alcuni server restituiscono deliberatamente 404 Not Found dove intendono 403, per evitare di confermare che una risorsa esiste affatto. Se un URL che sai essere reale torna come “non trovato” solo quando manca il permesso per accedervi, la vera risposta è 403 travestito.
Se è il tuo sito
Quale codice invii è una decisione, non un dettaglio, perché dice alla persona dall’altra parte quale dei due problemi molto diversi ha.
Invia 401 quando la richiesta non è autenticata - nessuna credenziale, o una che il server non può verificare - e includi un header WWW-Authenticate in modo che il client sappia come deve accedere. Un 401 è un invito ad autenticarsi e riprovare.
Invia 403 quando la richiesta è autenticata ma non consentita. L’utente è chi dice di essere e questo account non può farlo. Non rispondere con 401, perché 401 gli dice di accedere di nuovo, e lo farà, e fallirà di nuovo, e il ciclo non insegna loro nulla se non che il tuo sito è rotto.
La causa più comune di un 403 sul tuo sito è un controllo di permesso o ruolo: un utente che accede a una rotta admin, una chiave API senza l’ambito per un endpoint, un oggetto che appartiene a un altro account. La causa più comune di un 401 inaspettato è una sessione o token scaduto senza che il front end se ne accorga, quindi continua a inviare una credenziale che il server ha smesso di riconoscere.
Perché è meglio catturarli piuttosto che descriverli
“Ho ricevuto un errore e non mi ha fatto entrare” è il rapporto che di solito ricevi, e si adatta a entrambi i codici equamente, che è esattamente perché non aiuta. Un 401 e un 403 sembrano identici a un utente - una pagina che volevano e non hanno ricevuto - e l’unica informazione che li distingue, il codice di stato, è quella che una persona quasi mai pensa di leggere.
La richiesta stessa contiene la risposta: lo stato, se una credenziale è stata inviata con essa, e cosa ha detto il server. Catturata nel momento in cui è fallita, trasforma “non mi ha fatto entrare” in “un 403 su questo endpoint mentre acceduto con questo account”, che è un bug di permesso che qualcuno può trovare - piuttosto che un problema di login che qualcuno inseguirà per un’ora prima.
Session Replay
Estensione Chrome gratuita. Un clic sulla pagina che non funziona cattura lo screenshot, la console e il registro di rete, e ti dà un link da incollare nel ticket.
Il registro di rete contiene la richiesta fallita con il suo stato e se una credenziale è stata inviata con essa, quindi chiunque prenda il rapporto può vedere a colpo d’occhio se sta guardando un 401 o un 403 - e non deve riprodurre lo stato di accesso per scoprirlo. Per verificare se un URL restituisce uno di questi a te proprio ora, lo strumento di controllo dello stato HTTP lo richiede e riporta il codice che torna indietro.
In un paragrafo
Un 401 Unauthorized significa che il server non sa chi sei e dovresti autenticarti; un 403 Forbidden significa che sa esattamente chi sei e comunque non ti è permesso, quindi accedere di nuovo non aiuterà. Distinguili in base a se eri autenticato quando è successo, invia quello giusto dal tuo sito in modo che nessuno sia mandato in un ciclo di login per un problema di permesso, e cattura la richiesta fallita piuttosto che descriverla, perché il codice di stato è l’intera risposta e l’unica cosa che un utente non legge mai.