practices method how for example best authenticate http rest authentication web-applications web

method - Logins and Redirects: ¿Cuál es el mejor flujo HTTP para un inicio de sesión de webapp?



rest api header authentication (5)

Casi siempre uso la opción n. ° 2, simplemente porque el contenido devuelto por una URL es coherente. Si bien los secretos de hoy están ocultos detrás de un inicio de sesión, mañana es posible que desee abrirlo o mostrar público mixto / secreto dependiendo de la autenticación en la misma URL. En ese caso, la opción n. ° 2 se parecerá más a lo que Google esperaría. Google minimiza cualquier obstáculo e interruptor de contenido y, en el caso extremo, todas sus páginas tendrán contenido de página duplicado (es decir, formulario de inicio de sesión).

Esta pregunta es una pregunta sobre los flujos de inicio de sesión para aplicaciones web en general. Me interesan más las respuestas que optimizan la usabilidad y el rendimiento a la vez que mantienen la seguridad.

¿Cuál es la forma más adecuada de manejar las solicitudes no autenticadas a las URL marcadas?

Para demostrar el problema, aquí hay algunas rutas y comportamientos respectivos para una aplicación de ejemplo:

GET /login -> Display the authentication form POST /processLogin -> process the username and password, if unauthentic...re-render the login form; otherwise...display the default page GET /secret -> if authenticated...display the secret resource; otherwise...display a login form POST /secret -> if authenticated...perform a desirable, but potentially non-idempotent action on the secret resource otherwise...display a login form

Opción 1: Mostrar pantalla de inicio de sesión, redirigir a la página deseada

  1. Usuario hace clic en marcador
  2. GET / secret -> 200, muestra subrepticiamente el formulario de inicio de sesión con el campo oculto path = "/ secret"
  3. POST / processLogin -> 302 a / secret (valor del parámetro path)
  4. GET / secret -> 200, recurso secreto mostrado

Análisis: con suerte, su cliente es un navegador moderno, no compatible con HTTP, de modo que realiza un GET después de un POST de 302. Esto aplica en todos los ámbitos. ¿Deberia estar preocupado?

Opción 2: redirigir a la pantalla de inicio de sesión, redirigir a la página deseada

  1. Usuario hace clic en marcador
  2. OBTENER / secreto -> 302 a / iniciar sesión
  3. GET / login a través de redirigir -> 200, formulario de inicio de sesión que se muestra con el campo oculto path = "/ secret"
  4. POST / processLogin -> 302 a / secreto
  5. GET / secret -> 200, recurso secreto mostrado

Análisis: los mismos problemas que arriba. Se agregó el problema de que la URL mostrada por el navegador durante el inicio de sesión cambia, lo cual es confuso para el usuario y rompe los marcadores, el intercambio de enlaces, etc.

Opción 3: Mostrar pantalla de inicio de sesión, mostrar la página deseada

  1. Usuario hace clic en marcador
  2. GET / secret -> 200, subrepticiamente muestra el formulario de inicio de sesión con action = "/ secret"
  3. POST / secreto -> 200, recurso secreto mostrado

Análisis: Tristemente, el botón de actualización ahora también está roto: la actualización provocará que el agente de usuario vuelva a enviar el mensaje POST con una advertencia, en lugar de re-GETing / secret. El usuario recibe una advertencia, pero si lo ignoran, sucede algo malo.

En el lado positivo, minimizas los viajes de ida y vuelta con esta técnica.

Opción 4: redirigir a la pantalla de inicio de sesión, mostrar la página deseada

  1. Usuario hace clic en marcador
  2. GET / secret -> 302 a / processLogin
  3. GET / processLogin a través de redirigir -> 200, formulario de inicio de sesión que se muestra con action = "/ secret"
  4. POST / secreto -> 302 a / secreto
  5. GET / secret -> 200, recurso secreto mostrado

Análisis: los mismos problemas que las opciones 2 + 4.

Opción 5: ???

¿Hay otra técnica que me falta?

En general, ¿cuál de estas técnicas recomendaría?

Ver también

¿Cuál es el código de estado HTTP correcto al redireccionar a una página de inicio de sesión? ¿Qué tipo de redirección HTTP para inicios de sesión? Respuesta HTTP con redirección, pero sin ida y vuelta?


Las opciones 1 y 3 no siguen el RFC de HTTP ya que "mostrar subrepticiamente el formulario de inicio de sesión" contradice la respuesta 200 GET, donde se espera que "se envíe una entidad correspondiente al recurso solicitado en la respuesta".

La opción 2 está bien. Todos los navegadores modernos admiten 302 en POST y muchos marcos basados ​​en REST (como RoR) lo usan activamente. Alternativamente, en "302 para / iniciar sesión" ya puede crear la sesión (cookie) y almacenar la URL en sesión, para evitar pasar la URL original en los parámetros GET. Desde el punto de vista de la usabilidad, también puede tener un mensaje apropiado en la página de inicio de sesión (creo que la discrepancia de URL es irrelevante aquí; de todos modos, no puede permitir que el usuario vea el contenido).

Opción 4: cuando POST / secrete, HTTP RFC espera que "acepte la entidad incluida en la solicitud como un nuevo subordinado del recurso identificado por el URI de solicitud en la línea de solicitud", pero lo único que está haciendo es iniciar sesión y no crear nada nuevo bajo / secreto.

Entonces, después de HTTP RFC, su mejor opción es la Opción 2 . En realidad, la Opción 2 también está en línea con el patrón de diseño POST-> Redirigir-> GET , que ayuda a abordar el problema de la imprevisibilidad en los marcadores de URL a los recursos POST.


Mi $ .02: Recientemente implementé usando la opción 2 (aunque almacené /secret en una sesión, no en el formulario de inicio de sesión como un campo oculto).

No comparto completamente tus preocupaciones:

Se agregó el problema de que la URL mostrada por el navegador durante el inicio de sesión cambia, lo cual es confuso para el usuario y rompe los marcadores, el intercambio de enlaces, etc.

Al redirigir a /login , y al cambio posterior de URL, se le dice al usuario que antes de que puedan continuar, hay algo más que debe hacerse primero: iniciar sesión.

Dado que una página de inicio de sesión se verá completamente diferente de la ''página de destino'', no veo cómo eso confundirá a las personas en marcadores y / o enlaces compartiendo la página de inicio de sesión en lugar de la página de destino (ya que la página de inicio de sesión no contendrá información que desean marcar / compartir de todos modos).

Y si te preocupa que el 302 esté rompiendo el estándar (aunque todos y cada uno de los navegadores que conozco lo romperán felizmente), considera usar los 303 en su lugar.


Tenga en cuenta que mickeyreiss es correcto, y que la Opción AJAX 3 funciona sin el inconveniente del botón Atrás roto. Sin embargo, significa que el usuario debe tener JavaScript habilitado. Dicho esto, si programa su formulario correctamente, puede detectar si JS está presente, si no es así, use la Opción 1.

Tenga en cuenta que la respuesta 302 está bien, sin embargo, puede tener problemas con las memorias caché. Debe asegurarse de que no se almacene nada en la memoria caché si desea mostrar 2 páginas / formularios completamente diferentes para el mismo URI. (/ secreto que muestra el inicio de sesión y luego el secreto real).


Yo elegiría la opción usando AJAX:

  1. página de inicio de sesión y ocultar el contenido
  2. el usuario ingresa el nombre de usuario y la contraseña.
  3. La autenticación se realiza en el lado del servidor.
  4. El servidor devuelve un resultado
  5. si tiene éxito, use location.href para configurar la página a la que desea ir, o bien puede enviar un mensaje diciendo que el inicio de sesión no es válido.
  6. En su servidor, estará probando en una variable _SESSION , si no se establece redirigir a la página de inicio de sesión.