¿Cuál es el código de estado HTTP correcto al redirigir a una página de inicio de sesión?

133

Cuando un usuario no está conectado e intenta acceder a una página que requiere inicio de sesión, ¿cuál es el código de estado HTTP correcto para una redirección a la página de inicio de sesión?

Pregunto porque ninguno de los códigos de respuesta 3xx establecidos por el W3C parece cumplir con los requisitos:

10.3.1 300 opciones múltiples

El recurso solicitado corresponde a cualquiera de un conjunto de representaciones, cada una con su propia ubicación específica, y se proporciona información de negociación dirigida por el agente (sección 12) para que el usuario (o agente de usuario) pueda seleccionar una representación preferida y redirigir su solicitud a esa ubicación.

A menos que se trate de una solicitud HEAD, la respuesta DEBE incluir una entidad que contenga una lista de características de recursos y ubicaciones de las cuales el usuario o agente de usuario puede elegir la más adecuada. El formato de entidad se especifica por el tipo de medio dado en el campo de encabezado Tipo de contenido. Dependiendo del formato y las capacidades de

el agente de usuario, la selección de la opción más apropiada PUEDE realizarse automáticamente. Sin embargo, esta especificación no define ningún estándar para dicha selección automática.

Si el servidor tiene una opción preferida de representación, DEBE incluir el URI específico para esa representación en el campo Ubicación; los agentes de usuario PUEDEN usar el valor del campo Ubicación para la redirección automática. Esta respuesta se puede almacenar en caché a menos que se indique lo contrario.

10.3.2 301 Movido permanentemente

Al recurso solicitado se le ha asignado un nuevo URI permanente y cualquier referencia futura a este recurso DEBERÍA usar uno de los URI devueltos. Los clientes con capacidades de edición de enlaces deben volver a vincular automáticamente las referencias al Request-URI a una o más de las nuevas referencias devueltas por el servidor, cuando sea posible. Esta respuesta se puede almacenar en caché a menos que se indique lo contrario.

El nuevo URI permanente DEBE ser proporcionado por el campo Ubicación en la respuesta. A menos que el método de solicitud sea HEAD, la entidad de la respuesta DEBERÍA contener una breve nota de hipertexto con un hipervínculo a los nuevos URI.

Si el código de estado 301 se recibe en respuesta a una solicitud que no sea GET o HEAD, el agente de usuario NO DEBE redirigir automáticamente la solicitud a menos que pueda ser confirmada por el usuario, ya que esto podría cambiar las condiciones bajo las cuales se emitió la solicitud.

  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 encontrado

El recurso solicitado reside temporalmente bajo un URI diferente. Debido a que la redirección puede ser alterada ocasionalmente, el cliente DEBE continuar usando el URI de solicitud para futuras solicitudes. Esta respuesta solo se puede almacenar en caché si se indica mediante un campo de encabezado Cache-Control o Expires.

El URI temporal DEBE ser dado por el campo Ubicación en la respuesta. A menos que el método de solicitud sea HEAD, la entidad de la respuesta DEBE contener una breve nota de hipertexto con un hipervínculo a los nuevos URI.

Si se recibe el código de estado 302 en respuesta a una solicitud que no sea GET o HEAD, el agente de usuario NO DEBE redirigir automáticamente la solicitud a menos que pueda ser confirmada por el usuario, ya que esto podría cambiar las condiciones bajo las cuales se emitió la solicitud.

  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

fueron una respuesta 303, realizando un GET en el valor del campo Ubicación, independientemente del método de solicitud original. Los códigos de estado 303 y 307 se han agregado para los servidores que desean dejar inequívocamente claro qué tipo de reacción se espera del cliente.

10.3.4 303 Ver otros

La respuesta a la solicitud se puede encontrar bajo un URI diferente y DEBE recuperarse utilizando un método GET en ese recurso. Este método existe principalmente para permitir que la salida de un script activado por POST redirija al agente de usuario a un recurso seleccionado. El nuevo URI no es una referencia sustitutiva del recurso solicitado originalmente. La respuesta 303 NO DEBE almacenarse en caché, pero la respuesta a la segunda solicitud (redirigida) puede ser almacenable en caché.

Los diferentes URI DEBEN ser dados por el campo Ubicación en la respuesta. A menos que el método de solicitud sea HEAD, la entidad de la respuesta DEBE contener una breve nota de hipertexto con un hipervínculo a los nuevos 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 No modificado

Si el cliente ha realizado una solicitud GET condicional y se permite el acceso, pero el documento no se ha modificado, el servidor DEBE responder con este código de estado. La respuesta 304 NO DEBE contener un cuerpo de mensaje y, por lo tanto, siempre termina con la primera línea vacía después de los campos de encabezado.

La respuesta DEBE incluir los siguientes campos de encabezado:

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

el servidor de origen sin reloj obedece estas reglas, y los servidores proxy y los clientes agregan su propia Fecha a cualquier respuesta recibida sin una (como ya se especifica en [RFC 2068], sección 14.19), los cachés funcionarán correctamente.

  - 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

sección 13.3.3), la respuesta NO DEBE incluir otros encabezados de entidad. De lo contrario (es decir, el GET condicional utilizó un validador débil), la respuesta NO DEBE incluir otros encabezados de entidad; Esto evita inconsistencias entre los cuerpos de entidad en caché y los encabezados actualizados.

Si una respuesta 304 indica una entidad que actualmente no está en caché, entonces el caché DEBE ignorar la respuesta y repetir la solicitud sin el condicional.

Si un caché usa una respuesta 304 recibida para actualizar una entrada de caché, el caché DEBE actualizar la entrada para reflejar los nuevos valores de campo dados en la respuesta.

10.3.6 305 Usar proxy

Se debe acceder al recurso solicitado a través del proxy proporcionado por el campo Ubicación. El campo Ubicación proporciona el URI del proxy. Se espera que el destinatario repita esta solicitud única a través del proxy. Las respuestas 305 DEBEN ser generadas únicamente por los servidores de origen.

  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 (sin usar)

El código de estado 306 se usó en una versión anterior de la especificación, ya no se usa y el código está reservado.

10.3.8 307 Redirección temporal

El recurso solicitado reside temporalmente bajo un URI diferente. Dado que la redirección PUEDE ser alterada ocasionalmente, el cliente DEBE continuar utilizando el URI de solicitud para futuras solicitudes. Esta respuesta solo se puede almacenar en caché si se indica mediante un campo de encabezado Cache-Control o Expires.

El URI temporal DEBE ser dado por el campo Ubicación en la respuesta. A menos que el método de solicitud sea HEAD, la entidad de la respuesta DEBE contener una breve nota de hipertexto con un hipervínculo a los nuevos URI, ya que muchos agentes de usuario anteriores a HTTP / 1.1 no entienden el estado 307. Por lo tanto, la nota DEBE contener la información necesaria para que un usuario repita la solicitud original en el nuevo URI.

Si se recibe el código de estado 307 en respuesta a una solicitud que no sea GET o HEAD, el agente de usuario NO DEBE redirigir automáticamente la solicitud a menos que pueda ser confirmada por el usuario, ya que esto podría cambiar las condiciones bajo las cuales se emitió la solicitud.

Estoy usando 302 por ahora, hasta que encuentre la respuesta correcta.

Actualización y conclusión:

HTTP 302 es mejor ya que se sabe que tiene la mejor compatibilidad con clientes / navegadores.

Vidar Vestnes
fuente
1
Diría que absolutamente por el camino del libro sería devolver un 401 y una página de inicio de sesión sin una redirección, pero no estoy seguro de cuáles son sus opciones.
Nick Craver
1
@Nick buen punto, pero temería los efectos secundarios de eso si estuviera construyendo un sistema de inicio de sesión clásico.
Pekka
1
@Pekka - Absolutamente de acuerdo, depende de la plataforma en la que se encuentre esto en cuanto a cómo se puede manejar todo eso de manera limpia, también si entra en juego la intranet frente a Internet, creo ... normalmente la autenticación se realiza de manera diferente en una intranet, Al menos en mi experiencia.
Nick Craver
@Nick With 401 "La respuesta DEBE incluir un campo de encabezado WWW-Authenticate" - ¿Cómo puedo combinar esto con una base de datos MySQL? ¿No se limita AuthType Basic y Digest a archivos de configuración de apache como .htpassword, etc.?
Vidar Vestnes
Quiero una página de inicio de sesión personalizada, no el diálogo básico del navegador que pide nombre de usuario y contraseña ...
Vidar Vestnes

Respuestas:

66

Yo diría que 303 ver otros 302 encontrados:

El recurso solicitado reside temporalmente bajo un URI diferente. Debido a que la redirección puede ser alterada ocasionalmente , el cliente DEBE continuar usando el URI de solicitud para futuras solicitudes. Esta respuesta solo se puede almacenar en caché si se indica mediante un campo de encabezado Cache-Control o Expires.

se ajusta más a una página de inicio de sesión en mi opinión. Inicialmente consideré 303 see othercuál funcionaría igual de bien. Después de pensarlo un poco, diría que 302 Foundes más adecuado porque se encontró el recurso solicitado , solo hay otra página para pasar antes de que se pueda acceder. La respuesta no se almacena en caché de forma predeterminada, lo que también está bien.

Pekka
fuente
44
Estoy de acuerdo, pero creo que 302 Found indica que se encontró el recurso, justo debajo de otra url. Ex. Quiero se / my-messages / el servidor responde con un 302 porque "hoy" mis mensajes se encuentran en "/ login /" (en lugar de "/ messages /") ... Uso 302, pero no siento El contexto es 100% coincidente. Dado que la página de inicio de sesión es un recurso diferente y no tiene el mismo contenido solicitado.
Vidar Vestnes
2
@PHP_Jedi cierto. 303 puede ser más apropiado desde ese punto de vista. Sin embargo, 302 es más confiable en términos de compatibilidad del cliente.
Pekka
1
Sí, estoy pensando que 303 podría ajustarse mejor al contexto ya que dice "La respuesta a la solicitud se puede encontrar bajo un URI diferente". Esto me dice que no es el recurso en sí mismo el que se encuentra en otro URI, sino solo la respuesta a esta solicitud.
Vidar Vestnes
3
@PHP_Jedi No estoy seguro de si vale la pena dedicar tanto tiempo a esto. Tanto los clientes como los servidores en el mundo http tienen que ser extremadamente liberales y tolerantes a fallas de todos modos, por lo que no habrá una diferencia real si los usas 302o 303, excepto que 302es mejor conocido. Considero que el nivel de detalle es encomiable y siempre es bueno hacer las cosas bien, pero demasiado esfuerzo puede ser inútil en esta área específica.
Pekka
28
FYI: Google emite 302s
David Murdoch
51

Este es un mal uso del mecanismo de redirección HTTP. Si el usuario no está autorizado, su aplicación debe volver401 Unauthorized . En caso de que el usuario esté autorizado pero no tenga acceso al recurso solicitado, 403 Forbiddendebe devolverse.

Debe hacer la redirección en el lado del cliente, por ejemplo, mediante JavaScript. código de estado para la redirección porque no existe la autorización requerida . El uso de 30x para esto no se ajusta a HTTP.

Cómo pensar en los códigos de estado HTTP por Mark Nottingham

401 desencadena no autorizado mecanismo de autenticación de solicitud de HTTP.

401 UnauthorizedEl código de estado requiere la presencia de un WWW-Authenticateencabezado que admita varios tipos de autenticación:

Autenticación WWW: <tipo> realm = <realm>

Bearer, OAuth, Basic, Digest, Cookie, etc.

filip26
fuente
20
Un 401 puede no ser apropiado en algunos casos como A server generating a 401 (Unauthorized) response MUST send a WWW-Authenticate header field( RFC ), y no todos los sistemas de inicio de sesión usan ese encabezado.
starbeamrainbowlabs
66
Supongamos que está actualizando una página protegida; JavaScript del lado del cliente no tendrá ningún cambio para ser llamado, y el navegador abrirá una ventana de inicio de sesión en lugar de redirigir al usuario hacia la página de inicio de sesión, por lo que la única forma es usar un código 30x.
Claude Brisson,
2
Golang no puede usar 401 para la redirección. Eso significa que deberíamos usar 30 * para las redirecciones.
EIMEI
44
@EIMEI siguiendo su razonamiento, si otro idioma o biblioteca lo obligara a usar 401, entonces Internet estaría condenado. Mi punto es: lo que dices apunta a un problema con Golang (¡aunque me parece sorprendente que tenga un diseño así para que sea imposible enviar 401s!)
Greg
2
@starbeamrainbowlabs Hay un borrador para la autenticación HTTP basada en cookies como una opción en el encabezado WWW-Authenticate. Ver: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef
12

Creo que la solución adecuada es el encabezado HTTP 401 (no autorizado).

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

El propósito de este encabezado es exactamente esto. Pero, en lugar de redirigir a una página de inicio de sesión, el proceso correcto sería algo como:

  • El usuario no registrado intenta acceder a una página de inicio de sesión restringido.
  • el sistema identifica que el usuario no está registrado
  • el sistema devuelve el encabezado HTTP 401, y muestra el formulario de inicio de sesión en la misma respuesta (no una redirección).

Esta es una buena práctica, como proporcionar una página 404 útil, con enlaces de mapa del sitio y un formulario de búsqueda, por ejemplo.

Nos vemos.

Davis Peixoto
fuente
20
El RFC establece: "La respuesta DEBE incluir un campo de encabezado WWW-Authenticate (sección 14.46) que contenga un desafío aplicable al recurso solicitado". Una respuesta 401 solo es aplicable cuando se usa un esquema de autenticación HTTP.
bshacklett
44
En ese caso, 403 sería mejor, ya que establece que el acceso está simplemente prohibido y que el encabezado de autorización no ayudará
Olanod
@bshacklett WWW-Authenticate se puede usar junto con muchos esquemas de autenticación (por ejemplo, Bearer, OAuth). Ver developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… y iana.org/assignments/http-authschemes/http-authschemes.xhtml
filip26
Hay un borrador para la autenticación HTTP basada en cookies como una opción en el encabezado WWW-Authenticate. Ver: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef