Falha de login RESTful: Retorno 401 ou resposta personalizada

103

Esta é uma questão conceitual.

Tenho um aplicativo cliente (móvel) que precisa oferecer suporte a uma ação de login em um serviço da web RESTful. Como o serviço da web é RESTful, isso significa que o cliente aceita um nome de usuário / senha do usuário, verifica esse nome de usuário / senha com o serviço e, em seguida, lembra apenas de enviar esse nome de usuário / senha com todas as solicitações subsequentes.

Todas as outras respostas neste serviço da web são fornecidas em formato JSON.

A questão é, quando eu consulto o serviço da web simplesmente para descobrir se um determinado nome de usuário / senha é válido, o serviço da web deve sempre responder com dados JSON informando se foi bem ou malsucedido ou se ele deve retornar HTTP 200 em credenciais boas e HTTP 401 com credenciais incorretas.

O motivo de minha pergunta é que alguns outros serviços RESTful usam 401 para credenciais incorretas, mesmo quando você está apenas perguntando se as credenciais são válidas. No entanto, meu entendimento das respostas 401 é que elas representam um recurso ao qual você não deveria ter acesso sem credenciais válidas. Mas o recurso de login DEVE ser acessível a qualquer pessoa, porque todo o propósito do recurso de login é informar se suas credenciais são válidas.

Dito de outra forma, parece-me que um pedido como:

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

deve retornar 401 se credenciais incorretas forem fornecidas. Mas um pedido como:

myservice.com/are/these/credentials/valid

nunca deve retornar 401 porque esse URL específico (solicitação) está autorizado com ou sem credenciais válidas.

Eu gostaria de ouvir algumas opiniões justificadas de uma forma ou de outra sobre isso. Qual é a forma padrão de lidar com isso, e a forma padrão de lidar com isso é logicamente apropriada?

Matt
fonte

Respostas:

128

Primeiramente. 401 é o código de resposta adequado a enviar quando ocorre uma falha de login.

401 Unauthorized Semelhante a 403 Forbidden, mas especificamente para uso quando a autenticação é necessária e falhou ou ainda não foi fornecida. A resposta deve incluir um campo de cabeçalho WWW-Authenticate contendo um desafio aplicável ao recurso solicitado.

Sua confusão sobre, myservice.com/are/these/credentials/validenviar de volta 401 quando você apenas faz uma verificação, eu acho que é baseada no fato de que fazer solicitações booleanas em REST geralmente é errado pelas restrições RESTful. Cada solicitação deve retornar um recurso. Fazer perguntas booleanas em um serviço RESTful é uma tarefa escorregadia até o RPC.

Agora não sei como os serviços que você assistiu estão se comportando. Mas uma boa maneira de resolver isso é ter algo como um objeto Conta, que você tenta OBTER. Se suas credenciais estiverem corretas, você obterá o objeto Conta, se não quiser desperdiçar largura de banda apenas para uma "verificação" pode fazer um HEAD no mesmo recurso.

Um Objeto de conta também é um bom lugar para armazenar todos aqueles valores booleanos incômodos para os quais seria difícil criar recursos individuais.

Clérigo
fonte
2
Seu ponto sobre o retorno de recursos parece válido e talvez seja a jogada certa aqui. Quanto a afirmar que 401 é a resposta adequada, gostaria de receber alguma explicação aí. Eu li a especificação HTTP, como você incluiu aqui, mas isso para mim não é uma confirmação direta e óbvia de sua afirmação. Ou seja, a autenticação NÃO é exigida para perguntar sobre a validade das credenciais - mas o que você incluiu diz "especificamente para uso quando a autenticação for necessária".
Matt
3
Sua maneira de ver isso é correta. Você não precisa ser autenticado para solicitar seu objeto Conta. Mas você precisa se autenticar com sucesso para poder receber o recurso, e é isso que authentication is required and has failed or has not yet been providedse aplica, uma vez que você não pede a validade das credenciais, mas de um recurso específico com base nas credenciais fornecidas.
Clérigo
2
Eu entendo porque você deseja fazer uma "chamada de verificação" e, para isso, ainda promoveria 401 como o código de resposta apropriado para uma autenticação com falha, mesmo que a chamada não exija autenticação para poder ser chamada. Um 204 Sem conteúdo também pode ser adequado, mas parece um pouco ambíguo.
Clérigo
4
Não vejo como isso pode estar correto, a menos que você esteja usando autenticação Básica ou Digest. De acordo com a parte citada da especificação: "A resposta deve incluir uma autenticação WWW" - e se você consultar a seção 14.47: "O processo de autenticação de acesso HTTP é descrito em" Autenticação HTTP: autenticação de acesso básica e Digest ". Isso implica para mim, 401 não é apropriado se você estiver usando a validação típica de e-mail / senha.
Jonah
1
Acho que pode estar errado, tenho implementado clientes tanto web quanto mobile e intercepto o 401 para redirecionar para a tela de login. Mas quando alguém já está na tela de login e envia credenciais erradas, a resposta também tem 401 e tentará redirecionar novamente. Deve haver um código de status diferente para falha na tentativa de autenticação ao tentar explicitamente. Talvez um pedido ruim ou até mesmo um erro do servidor?
Japheth Ongeri - inkalimeva
28

401 deve ser enviado apenas quando a solicitação precisa do campo de cabeçalho de autorização e a autorização falha. Já que a API de login não requer autorização, portanto, 401 é o código de erro errado em minha opinião

De acordo com o padrão aqui https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

* 10.4.2 401 Não Autorizado

A solicitação requer autenticação do usuário. A resposta DEVE incluir um campo de cabeçalho WWW-Authenticate (seção 14.47) contendo uma contestação aplicável ao recurso solicitado. O cliente PODE repetir a solicitação com um campo de cabeçalho de autorização adequado (seção 14.8). Se a solicitação já incluiu credenciais de autorização, a resposta 401 indica que a autorização foi recusada para essas credenciais. Se a resposta 401 contiver o mesmo desafio que a resposta anterior, e o agente do usuário já tiver tentado a autenticação pelo menos uma vez, DEVERÁ ser apresentada ao usuário a entidade que foi dada na resposta, uma vez que essa entidade pode incluir informações diagnósticas relevantes. A autenticação de acesso HTTP é explicada em "Autenticação HTTP: Autenticação de Acesso Básica e Digest" [43]. *

vinksharma
fonte
8
Eu concordo com você, mas qual é o status de resposta alternativo a ser enviado? Tenho implementado clientes web e mobile e intercepto o 401 para redirecionar para a tela de login. Mas quando alguém já está na tela de login e envia credenciais erradas, a resposta também tem 401 e tentará redirecionar novamente ... o que você faria?
Japheth Ongeri - inkalimeva
0

Retorne 409 com uma mensagem de erro adequada.

camarão
fonte