Qual è il codice di stato HTTP corretto quando si reindirizza a una pagina di accesso?


133

Quando un utente non ha effettuato l'accesso e tenta di accedere a una pagina che richiede l'accesso, qual è il codice di stato HTTP corretto per un reindirizzamento alla pagina di accesso?

Lo sto chiedendo perché nessuno dei codici di risposta 3xx stabiliti dal W3C sembra soddisfare i requisiti:

10.3.1 300 scelte multiple

La risorsa richiesta corrisponde a una qualsiasi di una serie di rappresentazioni, ognuna con la propria posizione specifica e vengono fornite informazioni di negoziazione guidate dall'agente (sezione 12) in modo che l'utente (o agente utente) possa selezionare una rappresentazione preferita e reindirizzare la sua richiesta in quella posizione.

A meno che non si trattasse di una richiesta HEAD, la risposta DOVREBBE includere un'entità contenente un elenco di caratteristiche e ubicazioni delle risorse da cui l'utente o l'agente utente possono scegliere quello più appropriato. Il formato dell'entità è specificato dal tipo di supporto indicato nel campo di intestazione Tipo di contenuto. A seconda del formato e delle capacità di

l'agente utente, la selezione della scelta più appropriata PUO 'essere eseguita automaticamente. Tuttavia, questa specifica non definisce alcuno standard per tale selezione automatica.

Se il server ha una scelta preferita di rappresentazione, DOVREBBE includere l'URI specifico per quella rappresentazione nel campo Posizione; i programmi utente POSSONO utilizzare il valore del campo Posizione per il reindirizzamento automatico. Questa risposta è memorizzabile nella cache se non diversamente indicato.

10.3.2 301 spostato in modo permanente

Alla risorsa richiesta è stato assegnato un nuovo URI permanente e qualsiasi riferimento futuro a questa risorsa DOVREBBE utilizzare uno degli URI restituiti. I client con funzionalità di modifica dei collegamenti dovrebbero ricollegare automaticamente i riferimenti all'URI della richiesta a uno o più dei nuovi riferimenti restituiti dal server, ove possibile. Questa risposta è memorizzabile nella cache se non diversamente indicato.

Il nuovo URI permanente DOVREBBE essere indicato dal campo Posizione nella risposta. A meno che il metodo di richiesta non sia HEAD, l'entità della risposta DOVREBBE contenere una breve nota ipertestuale con un collegamento ipertestuale ai nuovi URI.

Se il codice di stato 301 viene ricevuto in risposta a una richiesta diversa da GET o HEAD, l'agente utente NON DEVE reindirizzare automaticamente la richiesta a meno che non possa essere confermata dall'utente, poiché ciò potrebbe modificare le condizioni in cui la richiesta è stata emessa.

  Note: When automatically redirecting a POST request after
  receiving a 301 status code, some existing HTTP/1.0 user agents
  will erroneously change it into a GET request.

10.3.3 302 trovati

La risorsa richiesta risiede temporaneamente con un URI diverso. Poiché il reindirizzamento potrebbe essere modificato in determinate occasioni, il client DOVREBBE continuare a utilizzare l'URI della richiesta per richieste future. Questa risposta è memorizzabile nella cache solo se indicata da un campo di intestazione Controllo cache o Scadenza.

L'URI temporaneo DOVREBBE essere indicato dal campo Posizione nella risposta. A meno che il metodo di richiesta non sia HEAD, l'entità della risposta DOVREBBE contenere una breve nota ipertestuale con un collegamento ipertestuale ai nuovi URI.

Se il codice di stato 302 viene ricevuto in risposta a una richiesta diversa da GET o HEAD, l'agente utente NON DEVE reindirizzare automaticamente la richiesta a meno che non possa essere confermata dall'utente, poiché ciò potrebbe modificare le condizioni in cui è stata emessa la richiesta.

  Note: RFC 1945 and RFC 2068 specify that the client is not allowed
  to change the method on the redirected request.  However, most
  existing user agent implementations treat 302 as if it

erano una risposta 303, eseguendo un OTTENERE sul valore del campo Posizione indipendentemente dal metodo di richiesta originale. I codici di stato 303 e 307 sono stati aggiunti per i server che desiderano chiarire in modo inequivocabile quale tipo di reazione è prevista per il client.

10.3.4 303 Vedi Altro

La risposta alla richiesta può essere trovata sotto un URI diverso e DOVREBBE essere recuperata utilizzando un metodo GET su quella risorsa. Questo metodo esiste principalmente per consentire all'output di uno script attivato POST di reindirizzare l'agente utente su una risorsa selezionata. Il nuovo URI non è un riferimento sostitutivo per la risorsa richiesta originariamente. La risposta 303 NON DEVE essere memorizzata nella cache, ma la risposta alla seconda richiesta (reindirizzata) potrebbe essere memorizzabile nella cache.

Il diverso URI DOVREBBE essere indicato dal campo Posizione nella risposta. A meno che il metodo di richiesta non sia HEAD, l'entità della risposta DOVREBBE contenere una breve nota ipertestuale con un collegamento ipertestuale ai nuovi URI.

  Note: Many pre-HTTP/1.1 user agents do not understand the 303
  status. When interoperability with such clients is a concern, the
  302 status code may be used instead, since most user agents react
  to a 302 response as described here for 303.

10.3.5 304 Non modificato

Se il client ha eseguito una richiesta GET condizionale e l'accesso è consentito, ma il documento non è stato modificato, il server DOVREBBE rispondere con questo codice di stato. La risposta 304 NON DEVE contenere un corpo di messaggio e quindi viene sempre terminata dalla prima riga vuota dopo i campi di intestazione.

La risposta DEVE includere i seguenti campi di intestazione:

  - Date, unless its omission is required by section 14.18.1 If a

il server di origine senza clock obbedisce a queste regole e i proxy e i client aggiungono la propria Data a qualsiasi risposta ricevuta senza una (come già specificato da [RFC 2068], sezione 14.19), le cache funzioneranno correttamente.

  - ETag and/or Content-Location, if the header would have been sent
    in a 200 response to the same request
  - Expires, Cache-Control, and/or Vary, if the field-value might
    differ from that sent in any previous response for the same
    variant If the conditional GET used a strong cache validator (see

sezione 13.3.3), la risposta NON DOVREBBE includere altre intestazioni di entità. Altrimenti (ovvero, il GET condizionale utilizzava un validatore debole), la risposta NON DEVE includere altre intestazioni di entità; questo evita incoerenze tra i corpi di entità cache e le intestazioni aggiornate.

Se una risposta 304 indica un'entità non attualmente memorizzata nella cache, la cache DEVE ignorare la risposta e ripetere la richiesta senza il condizionale.

Se una cache utilizza una risposta 304 ricevuta per aggiornare una voce della cache, la cache DEVE aggiornare la voce per riflettere eventuali nuovi valori di campo forniti nella risposta.

10.3.6 305 Usa proxy

È necessario accedere alla risorsa richiesta tramite il proxy fornito dal campo Posizione. Il campo Posizione fornisce l'URI del proxy. Il destinatario dovrebbe ripetere questa singola richiesta tramite il proxy. 305 risposte DEVONO essere generate solo dai server di origine.

  Note: RFC 2068 was not clear that 305 was intended to redirect a
  single request, and to be generated by origin servers only.  Not
  observing these limitations has significant security consequences.

10.3.7 306 (Non utilizzato)

Il codice di stato 306 era utilizzato in una versione precedente della specifica, non è più utilizzato e il codice è riservato.

10.3.8 307 Reindirizzamento temporaneo

La risorsa richiesta risiede temporaneamente con un URI diverso. Poiché il reindirizzamento POTREBBE essere modificato occasionalmente, il client DOVREBBE continuare a utilizzare l'URI della richiesta per richieste future. Questa risposta è memorizzabile nella cache solo se indicata da un campo di intestazione Controllo cache o Scadenza.

L'URI temporaneo DOVREBBE essere indicato dal campo Posizione nella risposta. A meno che il metodo di richiesta non sia HEAD, l'entità della risposta DOVREBBE contenere una breve nota ipertestuale con un collegamento ipertestuale ai nuovi URI, poiché molti agenti utente pre-HTTP / 1.1 non comprendono lo stato 307. Pertanto, la nota DOVREBBE contenere le informazioni necessarie affinché un utente possa ripetere la richiesta originale sul nuovo URI.

Se il codice di stato 307 viene ricevuto in risposta a una richiesta diversa da GET o HEAD, l'agente utente NON DEVE reindirizzare automaticamente la richiesta a meno che non possa essere confermata dall'utente, poiché ciò potrebbe modificare le condizioni in cui è stata emessa la richiesta.

Sto usando 302 per ora, fino a quando non trovo la risposta corretta.

Aggiornamento e conclusione:

HTTP 302 è migliore poiché è noto per avere la migliore compatibilità con client / browser.


1
Direi assolutamente dal modo in cui il libro sarebbe di restituire un 401 e una pagina di accesso senza reindirizzamento, ma non sono sicuro di quali siano le tue opzioni.
Nick Craver

1
@Nick buon punto, ma temerei effetti collaterali da quello se stavo costruendo un sistema di login classico.
Pekka,

1
@Pekka - Assolutamente d'accordo, dipende da quale piattaforma si trova su come tutto ciò che può essere gestito in modo pulito, anche se entra in gioco la sua intranet vs internet credo ... in genere fai l'autenticazione in modo diverso su una intranet, almeno nella mia esperienza.
Nick Craver

@Nick With 401 "La risposta DEVE includere un campo di intestazione WWW-Authenticate" - Come posso combinare questo con un database MySQL? AuthType Basic e Digest non sono limitati ai file di configurazione di apache come .htpassword ecc ...?
Vidar Vestnes,

Voglio una pagina di accesso personalizzata, non la finestra di dialogo del browser di base che richiede nome utente e password ...
Vidar Vestnes,

Risposte:


66

Direi 303 vedi altri 302 trovati:

La risorsa richiesta risiede temporaneamente con un URI diverso. Poiché il reindirizzamento potrebbe essere modificato in determinate occasioni , il client DOVREBBE continuare a utilizzare l'URI della richiesta per richieste future. Questa risposta è memorizzabile nella cache solo se indicata da un campo di intestazione Controllo cache o Scadenza.

a mio avviso, si adatta più da vicino a una pagina di accesso. Inizialmente ho pensato 303 see otherche avrebbe funzionato altrettanto bene. Dopo qualche pensiero, direi che 302 Foundè più appropriato perché la risorsa richiesta era trovata, c'è solo un'altra pagina da visitare prima che sia possibile accedervi. La risposta non viene memorizzata nella cache per impostazione predefinita, il che va bene anche.


4
Sono d'accordo, ma penso che 302 Found indichi che la risorsa è stata trovata, proprio sotto un altro URL. Ex. Voglio vedere / i miei messaggi / il server risponde con un 302 perché "oggi" i miei messaggi si trovano in "/ login /" (invece di "/ messaggi /") ... Uso 302, ma non mi sento il contesto corrisponde al 100%. Poiché la pagina di accesso è una risorsa diversa e non ha lo stesso contenuto richiesto.
Vidar Vestnes,

2
@PHP_Jedi true. 303 potrebbe essere più appropriato da quel punto di vista. Tuttavia, 302 è più affidabile in termini di compatibilità client.
Pekka,

1
Sì, sto pensando che 303 potrebbe adattarsi meglio al contesto poiché afferma "La risposta alla richiesta può essere trovata sotto un URI diverso". Questo mi sta dicendo che non è la risorsa stessa che si trova in un altro URI, ma solo la risposta a questa richiesta.
Vidar Vestnes,

3
@PHP_Jedi Non sono sicuro se valga la pena dedicare così tanto tempo a questo. Sia i client che i server nel mondo http devono comunque essere estremamente liberali e tolleranti agli errori, quindi non ci sarà alcuna reale differenza se lo usi 302o 303, tranne che 302è meglio conosciuto. Trovo il livello di dettaglio encomiabile ed è sempre bello fare le cose nel modo giusto, ma troppi sforzi potrebbero essere vani in questa specifica area.
Pekka,

28
Cordiali saluti: Google rilascia 302s
David Murdoch il

51

Questo è un uso improprio del meccanismo di reindirizzamento HTTP. Se l'utente non è autorizzato, l'app deve essere restituita 401 Unauthorized. Nel caso in cui l'utente sia autorizzato ma non abbia accesso alla risorsa richiesta, 403 Forbiddendeve essere restituito.

Dovresti fare il reindirizzamento sul lato client, ad esempio tramite javascript. codice di stato per il reindirizzamento perché non esiste l'autorizzazione richiesta . L'uso di 30x per questo non è conforme a HTTP.

Come pensare ai codici di stato HTTP di Mark Nottingham

401 Non autorizzato attiva il meccanismo di autenticazione della richiesta HTTP.

401 Unauthorizedil codice di stato richiede la presenza di WWW-Authenticateintestazione che supporti vari tipi di autenticazione:

WWW-Authenticate: <type> realm = <realm>

Bearer, OAuth, Basic, Digest, Cookie, ecc


20
Un 401 potrebbe non essere appropriato in alcuni casi come A server generating a 401 (Unauthorized) response MUST send a WWW-Authenticate header field( RFC ) e non tutti i sistemi di accesso utilizzano quell'intestazione.
Starbeamrainbowlabs

6
Supponiamo di aggiornare una pagina protetta; javascript lato client non avrà alcuna modifica per essere chiamato, e il browser aprirà una finestra di accesso invece di reindirizzare l'utente verso la pagina di accesso - quindi l'unico modo è usare un codice 30x.
Claude Brisson,

2
Golang non può usare 401 per il reindirizzamento. Ciò significa che dovremmo usare 30 * per i reindirizzamenti.
EIMEI

4
@EIMEI seguendo il tuo ragionamento, se un'altra lingua o libreria ti ha costretto a usare 401, Internet sarebbe condannato. Il mio punto è: ciò che dici indica un problema con Golang (anche se trovo sorprendente che avrebbe un tale design da rendere impossibile l'invio di 401!)
Greg

2
@starbeamrainbowlabs Esiste una bozza per l'autenticazione HTTP basata su cookie come opzione nell'intestazione WWW-Authenticate. Vedi: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef

12

Penso che la soluzione appropriata sia l'intestazione HTTP 401 (non autorizzata).

http://en.wikipedia.org/wiki/HTTP_codes#4xx_Client_Error

Lo scopo di questa intestazione è esattamente questo. Ma, invece di reindirizzare a una pagina di accesso, il processo corretto sarebbe qualcosa del tipo:

  • L'utente non registrato tenta di accedere a una pagina con accesso limitato.
  • il sistema identifica l'utente non è registrato
  • il sistema restituisce l'intestazione HTTP 401 e visualizza il modulo di accesso nella stessa risposta (non un reindirizzamento).

Questa è una buona pratica, come fornire una pagina 404 utile, con collegamenti a sitemap e, ad esempio, un modulo di ricerca.

Ci vediamo.


20
La RFC afferma: "La risposta DEVE includere un campo di intestazione WWW-Authenticate (sezione 14.46) contenente una sfida applicabile alla risorsa richiesta." Una risposta 401 è realmente applicabile solo quando si utilizza uno schema di autenticazione HTTP.
bshacklett,

4
In tal caso 403 sarebbe meglio poiché afferma che l'accesso è semplicemente vietato e l'intestazione dell'autorizzazione non aiuterà
olanod

@bshacklett WWW-Authenticate può essere utilizzato insieme a molti schemi di autenticazione (ad esempio Bearer, OAuth). Vedi developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… e iana.org/assignments/http-authschemes/http-authschemes.xhtml
filip26

Esiste una bozza per l'autenticazione HTTP basata su cookie come opzione nell'intestazione WWW-Authenticate. Vedi: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.