Error de inicio de sesión RESTful: Devolver 401 o respuesta personalizada

103

Ésta es una cuestión conceptual.

Tengo una aplicación cliente (móvil) que debe admitir una acción de inicio de sesión contra un servicio web RESTful. Debido a que el servicio web es RESTful, esto equivale a que el cliente acepte un nombre de usuario / contraseña del usuario, verifique ese nombre de usuario / contraseña con el servicio y luego recuerde enviar ese nombre de usuario / contraseña con todas las solicitudes posteriores.

Todas las demás respuestas de este servicio web se proporcionan en formato JSON.

La pregunta es, cuando consulto el servicio web simplemente para averiguar si un nombre de usuario / contraseña dado son válidos, si el servicio web siempre responde con datos JSON diciéndome que es exitoso o no exitoso, o debe devolver HTTP 200 con buenas credenciales y HTTP 401 con credenciales incorrectas.

La razón por la que pregunto es que algunos otros servicios RESTful usan 401 para credenciales incorrectas, incluso cuando solo pregunta si las credenciales son válidas. Sin embargo, mi entendimiento de las respuestas 401 es que representan un recurso al que se supone que no debes tener acceso sin credenciales válidas. Pero el recurso de inicio de sesión DEBE ser accesible para cualquier persona porque el propósito completo del recurso de inicio de sesión es informarle si sus credenciales son válidas.

Dicho de otra manera, me parece que una solicitud como:

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

debe devolver 401 si se proporcionan credenciales incorrectas. Pero una solicitud como:

myservice.com/are/these/credentials/valid

nunca debe devolver 401 porque esa URL en particular (solicitud) está autorizada con o sin credenciales válidas.

Me gustaría escuchar algunas opiniones justificadas de una forma u otra sobre esto. ¿Cuál es la forma estándar de manejar esto y es la forma estándar de manejar esto lógicamente apropiada?

Mate
fuente

Respuestas:

128

Antes que nada. 401 es el código de respuesta adecuado para enviar cuando se produce un inicio de sesión fallido.

401 No autorizado Similar al 403 Prohibido, pero específicamente para usar cuando se requiere autenticación y ha fallado o aún no se ha proporcionado. La respuesta debe incluir un campo de encabezado WWW-Authenticate que contenga un desafío aplicable al recurso solicitado.

Tu confusión sobre myservice.com/are/these/credentials/valid enviar 401 cuando acaba de hacer una verificación, creo que se basa en el hecho de que hacer solicitudes booleanas en REST a menudo es incorrecto por las restricciones RESTful. Cada solicitud debe devolver un recurso. Hacer preguntas booleanas en un servicio RESTful es un balandro resbaladizo hasta RPC.

Ahora no sé cómo se están comportando los servicios que miraste. Pero una buena forma de resolver esto es tener algo como un objeto Cuenta, que intentas OBTENER. Si sus credenciales son correctas, obtendrá el objeto Cuenta, si no desea desperdiciar ancho de banda solo para "verificar", puede hacer un HEAD en el mismo recurso.

Un objeto de cuenta también es un buen lugar para almacenar todos esos molestos valores booleanos para los que de otro modo sería complicado crear recursos individuales.

Clérigo
fuente
2
Su punto sobre la devolución de recursos parece válido y tal vez ese sea el movimiento correcto aquí. En cuanto a afirmar que 401 es la respuesta adecuada, agradecería alguna explicación allí. He leído la especificación HTTP, como la ha incluido aquí, pero para mí eso no se lee como una confirmación directa y obvia de su afirmación. Es decir, NO se requiere autenticación para preguntar sobre la validez de las credenciales; sin embargo, lo que incluyó dice "específicamente para usar cuando se requiere autenticación".
Matt
3
Tu forma de verlo es correcta. No necesita estar autenticado para poder solicitar su objeto Cuenta. Pero debe autenticarse con éxito para poder recibir el recurso, y ahí es donde se authentication is required and has failed or has not yet been providedaplica, ya que no solicita la validez de las credenciales, sino un recurso específico basado en las credenciales que proporciona.
Clérigo
2
Entiendo por qué quiere hacer una "llamada de verificación" y, para eso, todavía promocionaría 401 como el código de respuesta apropiado para una autenticación fallida, incluso si la llamada no requiere autenticación para poder llamar. Un 204 Sin contenido también puede ser adecuado, pero se siente un poco ambiguo.
Clérigo
4
No veo cómo esto puede ser correcto, a menos que esté utilizando la autenticación básica o implícita. Según la parte citada de la especificación: "La respuesta debe incluir un WWW-Authenticate", y si se refiere a la sección 14.47: "El proceso de autenticación de acceso HTTP se describe en" Autenticación HTTP: autenticación de acceso básica y implícita ". Esto implica Para mí, el 401 no es apropiado si está utilizando la validación típica de correo electrónico / contraseña.
Jonah
1
Creo que esto puede estar mal, he estado implementando clientes tanto web como móviles e intercepto el 401 para redirigirlo a la pantalla de inicio de sesión. Pero cuando alguien ya está en la pantalla de inicio de sesión y envía credenciales incorrectas, la respuesta también tiene 401 e intentará redirigir nuevamente. Debe haber un código de estado diferente para el intento fallido de autenticarse cuando se intenta explícitamente. ¿Quizás una solicitud incorrecta o incluso un error del servidor?
Japheth Ongeri - inkalimeva
28

401 debe enviarse solo cuando la solicitud necesita un campo de encabezado de autorización y la autorización falla. Dado que la API de inicio de sesión no requiere autorización, 401 es el código de error incorrecto en mi opinión

Según el estándar aquí https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

* 10.4.2 401 no autorizado

La solicitud requiere autenticación de usuario. La respuesta DEBE incluir un campo de encabezado WWW-Authenticate (sección 14.47) que contenga un desafío aplicable al recurso solicitado. El cliente PUEDE repetir la solicitud con un campo de encabezado de autorización adecuado (sección 14.8). Si la solicitud ya incluía credenciales de autorización, entonces la respuesta 401 indica que se ha rechazado la autorización para esas credenciales. Si la respuesta 401 contiene el mismo desafío que la respuesta anterior, y el agente de usuario ya ha intentado la autenticación al menos una vez, entonces se DEBE presentar al usuario la entidad que se le dio en la respuesta, ya que esa entidad podría incluir información de diagnóstico relevante. La autenticación de acceso HTTP se explica en "Autenticación HTTP: autenticación de acceso básica y implícita" [43]. *

vinksharma
fuente
8
Estoy de acuerdo contigo en esto, pero ¿cuál es el estado de respuesta alternativo para enviar? He estado implementando clientes tanto web como móviles e intercepto 401 para redirigir a la pantalla de inicio de sesión. Pero cuando alguien ya está en la pantalla de inicio de sesión y envía credenciales incorrectas, la respuesta también tiene 401 e intentará redirigir nuevamente ... ¿qué harías?
Japheth Ongeri - inkalimeva
0

Devuelve 409 con un mensaje de error adecuado.

vagón de camarones
fuente