Errore di accesso RESTful: restituzione 401 o risposta personalizzata


103

Questa è una domanda concettuale.

Ho un'applicazione client (mobile) che deve supportare un'azione di accesso su un servizio web RESTful. Poiché il servizio Web è RESTful, ciò equivale al client che accetta un nome utente / password dall'utente, verificando tale nome utente / password con il servizio e quindi ricordandosi di inviare quel nome utente / password con tutte le richieste successive.

Tutte le altre risposte in questo servizio Web vengono fornite in formato JSON.

La domanda è: quando interrogo il servizio Web semplicemente per scoprire se un determinato nome utente / password è valido, il servizio Web dovrebbe sempre rispondere con dati JSON che mi dicono che ha avuto successo o meno, o dovrebbe restituire HTTP 200 con buone credenziali e HTTP 401 su cattive credenziali.

Il motivo per cui lo chiedo è che alcuni altri servizi RESTful usano 401 per cattive credenziali anche quando stai solo chiedendo se le credenziali sono valide. Tuttavia, la mia comprensione delle risposte 401 è che rappresentano una risorsa a cui non dovresti avere accesso senza credenziali valide. Ma la risorsa di accesso DOVREBBE essere accessibile a chiunque perché l'intero scopo della risorsa di accesso è di dirti se le tue credenziali sono valide.

In altre parole, mi sembra che una richiesta del tipo:

myservice.com/this/is/a/user/action 

dovrebbe restituire 401 se vengono fornite credenziali errate. Ma una richiesta come:

myservice.com/are/these/credentials/valid

non dovrebbe mai restituire 401 perché quel particolare URL (richiesta) è autorizzato con o senza credenziali valide.

Mi piacerebbe sentire alcune opinioni giustificate in un modo o nell'altro su questo. Qual è il modo standard di gestirlo, ed è il modo standard di gestirlo logicamente appropriato?

Risposte:


128

Prima di tutto. 401 è il codice di risposta corretto da inviare quando si è verificato un accesso non riuscito.

401 Non autorizzato Simile a 403 Proibito, ma specifico per l'uso quando è richiesta l'autenticazione e non è riuscita o non è stata ancora fornita. La risposta deve includere un campo di intestazione WWW-Authenticate contenente una sfida applicabile alla risorsa richiesta.

La tua confusione su myservice.com/are/these/credentials/valid all'invio di 401 quando fai solo un controllo, penso sia basata sul fatto che fare richieste booleane in REST spesso è sbagliato dai vincoli RESTful. Ogni richiesta dovrebbe restituire una risorsa. Fare domande booleane in un servizio RESTful è uno sloop scivoloso fino a RPC.

Ora non so come si stanno comportando i servizi che hai guardato. Ma un buon modo per risolvere questo problema è avere qualcosa come un oggetto Account, che cerchi di OTTENERE. Se le tue credenziali sono corrette, otterrai l'oggetto Account, se non vuoi sprecare larghezza di banda solo per un "controllo" puoi fare un HEAD sulla stessa risorsa.

Un oggetto account è anche un bel posto per memorizzare tutti quei fastidiosi valori booleani per i quali altrimenti sarebbe difficile creare risorse individuali.


2
Il tuo punto di vista sulla restituzione delle risorse sembra valido e forse questa è la mossa giusta qui. Per quanto riguarda l'affermazione che 401 è la risposta corretta, apprezzerei alcune spiegazioni. Ho letto le specifiche HTTP, come hai incluso qui, ma per me non si legge come una conferma diretta e ovvia della tua affermazione. Vale a dire, l'autenticazione NON è richiesta per chiedere informazioni sulla validità delle credenziali, ma ciò che hai incluso dice "specificamente per l'uso quando è richiesta l'autenticazione".
Matt

3
Il tuo modo di vederlo è corretto. Non è necessario essere autenticati per poter richiedere l'oggetto Account. Ma è necessario autenticarsi correttamente per poter ricevere la risorsa, ed è qui che si authentication is required and has failed or has not yet been providedapplica, poiché non si richiede la validità delle credenziali, ma una risorsa specifica in base alle credenziali fornite.
Chierico

2
Capisco perché vuoi fare una "chiamata di controllo" e per questo, promuoverei comunque 401 come codice di risposta appropriato per un'autenticazione fallita, anche se la chiamata non richiede l'autenticazione per essere richiamabile. Anche un 204 No Content potrebbe essere adatto, ma sembra un po 'ambiguo.
Chierico

4
Non vedo come questo possa essere corretto, a meno che tu non stia utilizzando l'autenticazione di base o del digest. Secondo la parte citata della specifica: "La risposta deve includere un'autenticazione WWW" - e se si fa riferimento alla sezione 14.47: "Il processo di autenticazione dell'accesso HTTP è descritto in" Autenticazione HTTP: autenticazione di accesso di base e digest ". Ciò implica per me che 401 non è appropriato se si utilizza la tipica convalida di email / password.
Jonah

1
Penso che questo possa essere sbagliato, ho implementato client sia web che mobile e intercetto 401 per reindirizzare alla schermata di accesso. Ma quando qualcuno è già nella schermata di accesso e invia credenziali errate, anche la risposta ha 401 e proverà a reindirizzare nuovamente. Dovrebbe esserci un codice di stato diverso per il tentativo non riuscito di ottenere l'autenticazione durante il tentativo esplicito. Forse una cattiva richiesta o addirittura un errore del server?
Japheth Ongeri - inkalimeva

27

401 deve essere inviato solo quando la richiesta richiede il campo dell'intestazione dell'autorizzazione e l'autorizzazione non riesce. Poiché l'API di accesso non richiede l'autorizzazione, quindi 401 è il codice di errore sbagliato secondo me

Come da standard qui https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

* 10.4.2 401 Non autorizzato

La richiesta richiede l'autenticazione dell'utente. La risposta DEVE includere un campo di intestazione WWW-Authenticate (sezione 14.47) contenente una sfida applicabile alla risorsa richiesta. Il cliente PUO 'ripetere la richiesta con un apposito campo di intestazione di autorizzazione (sezione 14.8). Se la richiesta includeva già le credenziali di autorizzazione, la risposta 401 indica che l'autorizzazione è stata rifiutata per tali credenziali. Se la risposta 401 contiene la stessa sfida della risposta precedente e l'agente utente ha già tentato l'autenticazione almeno una volta, allora all'utente DOVREBBE essere presentata l'entità che è stata fornita nella risposta, poiché tale entità potrebbe includere informazioni diagnostiche rilevanti. L'autenticazione dell'accesso HTTP è spiegata in "Autenticazione HTTP: autenticazione di accesso di base e digest" [43]. *


8
Sono d'accordo con te su questo, ma qual è lo stato di risposta alternativo da inviare? Sto implementando client sia web che mobile e intercetto 401 per reindirizzare alla schermata di accesso. Ma quando qualcuno è già nella schermata di accesso e invia credenziali errate, anche la risposta ha 401 e proverà a reindirizzare di nuovo ... cosa faresti?
Japheth Ongeri - inkalimeva

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.