¿Qué código de estado http se supone que debe usarse para decirle al cliente que se agotó el tiempo de espera de la sesión?

80

En una página web, utiliza el administrador de conexión / fuente de datos YUI para enviar solicitudes AJAX al servidor, si la sesión (que contiene la información sobre si el usuario ha sido autenticado) ya ha agotado el tiempo de espera, esas respuestas ajax que solo pueden ser vistas por autenticados los usuarios deben devolver un código de estado http, indicándole al cliente que la sesión ya ha agotado el tiempo de espera, luego el cliente simplemente lo redirige a la página de inicio de sesión o le pregunta si quiere extender la sesión.

Mi pregunta es que, en esta situación, ¿qué código de estado http es el más apropiado para decirle al cliente que se agotó el tiempo de espera de la sesión?

Lista de códigos de estado HTTP de wiki

bobo
fuente
¿Quiere advertir al usuario que la sesión está a punto de caducar para que el usuario pueda hacer algo para renovarla? Si ese es el caso, tendría que ser manejado por un temporizador en JavaScript que se apaga antes del tiempo de espera de la sesión en el servidor. Para cuando el servidor envíe el código de estado, ya habrá expirado. También se necesitaría un temporizador si los redirigiera a otra página automáticamente si dejaran la página inactiva.
Jason
8
¡Por supuesto, 418! Corto y robusto ...
Tim Post
Vaadin usa 410 Gone, pero dado que el navegador lo puede almacenar en caché, no lo recomendaría
sreg

Respuestas:

66

Lo mejor que puedo sugerir es un código de estado HTTP 401 con un encabezado WWW-Authenticate.

El problema con las solicitudes 403 es que el RFC 2616 dice "La autorización no ayudará y la solicitud NO DEBE repetirse". (es decir, no importa si está autenticado o no, nunca tendrá acceso a ese recurso).

El problema con las solicitudes 401 es que indica que "DEBEN incluir un campo de encabezado WWW-Authenticate". Como alguien ha notado , no parece infringir la especificación utilizar un valor personalizado en un encabezado WWW-Authenticate.

No veo ninguna razón en RFC 2617 por la que un estado HTTP 401 combinado con un encabezado WWW-Authenticate personalizado como este no estaría bien:

WWW-Authenticate: MyAuthScheme realm="http://example.com"

La especificación oAuth realmente parece hacer exactamente esto, ya que recomiendan esto (aunque en mi opinión tienen una interpretación extraña del RFC):

WWW-Authenticate: OAuth realm="http://server.example.com/"

Esto no parece estar específicamente SANCIONADO por el RFC, pero en realidad no puedo ver que esté prohibido por él (no parece entrar en conflicto con ninguna condición DEBE o NO DEBE, DEBE o NO DEBE).

Desearía que hubiera un código de estado HTTP más específico para los tiempos de espera y para cosas como los tokens CSRF que no son válidos para que esto sea más claro.

Iain Collins
fuente
34

Recomendaría un HTTP 401.

Mientras que un 403 básicamente dice: "No tienes permiso, vete y no vuelvas", un 401 dice: "No sabemos si tienes permiso o no porque no trajiste tu identificación. Ir consígalo y vuelva a intentarlo ".

Compare las definiciones de Wikipedia :

HTTP 403 : la solicitud era una solicitud legal, pero el servidor se niega a responder.

HTTP 401 : similar a 403 Prohibido, pero específicamente para usar cuando la autenticación es posible pero ha fallado o aún no se ha proporcionado.

Jonathon Hill
fuente
3
401 está destinado a la autenticación HTTP . RFC 2616 dice response MUST include a WWW-Authenticate header field. Por lo tanto, es incorrecto enviar ese código sin un campo de encabezado WWW-Authenticate .
Toxalot
19

¿Qué pasa con 419? No es estándar, pero la descripción en Wikipedia parece encajar:

419 Tiempo de espera de autenticación

No es parte del estándar HTTP, 419 Authentication Timeout denota que la autenticación previamente válida ha expirado. Se utiliza como alternativa a 401 No autorizado para diferenciar a los clientes autenticados a los que se les niega el acceso a recursos específicos del servidor.

John Reichert
fuente
14
¿Alguna idea de dónde viene esto (que no sea Wikipedia)? Si no está en el RFC oficial, ¿quién lo definió?
anaximandro
5
Parece que también se eliminó de esa página wiki
Salem Ouerdani
Esto no es parte de la especificación, ni está disponible en Java HttpServletResponse@John. Si conoce otra fuente confiable, es mejor hacer referencia a ella.
Vishrant
Parece que solo se usa en PHP Laravel
TroySteven
12

Creo que el código apropiado será 403 / Prohibido. No hay ninguno que esté directamente relacionado con las sesiones.

Jason
fuente
1
Absolutamente esta es la respuesta correcta. Dado que la sesión ha expirado, la solicitud está prohibida, por lo que esta es la mejor opción.
marcc
3
403 le dice al cliente (básicamente) "No vuelva a hacer eso a menos que modifique su solicitud", pero si se estableció la sesión, no se necesitaría ninguna modificación. Además, no puede hacer nada con la solicitud (actual) para restablecer la sesión en la mayoría de los casos.
Tim Post
1
¡Exactamente! 401 sería mejor, creo, pero requiere autenticación HTTP. Creo que esto requiere un nuevo estado en la línea de 401 + 303 (entonces, obviamente, 704) que significa "No autorizado, ver otro para obtener autorización". Además de ser más semánticamente correcto, también podría ser la solución HTTP para la redirección de trampolín, básicamente "ve aquí, luego, cuando regreses, lo intentaremos de nuevo", de modo que la página de inicio de sesión pueda ser agnóstica con respecto a la destino.
Anthony
5
No puedo estar de acuerdo con esto, RFC 2616 establece explícitamente que las solicitudes que dan como resultado una respuesta 403 "NO DEBEN ser repetidas" por el cliente y que "la autorización no ayudará".
Iain Collins
5
authorization will not help- Entiendo que eso significa que la autenticación HTTP no ayudará. Cual es correcta. Enviar un encabezado de autorización no cambiará nada. Ni 401 ni 403 son ideales, pero creo que 403 es mejor que 401. 401 es incorrecto para el tiempo de espera de la sesión porque RFC 2616 establece explícitamente client MAY repeat the request with a suitable Authorization header field. Pero, en este caso, el cliente NO DEBE repetir la solicitud (al menos no sin un paso intermedio). Desafortunadamente, no podemos comunicar la última parte con un código de estado.
Toxalot
11

La verdad es que no existe un código de estado HTTP estándar para un tiempo de espera de sesión. Las sesiones se implementan en la capa de aplicación, no en la capa de transporte HTTP.

Hay un código de estado personalizado que Microsoft ha estado usando para el tiempo de espera de la sesión: 599, o simplemente cree su propio código de estado en el rango 5xx.

Desde el Wiki de códigos de estado:

599 Error de tiempo de espera de conexión de red (Desconocido) Este código de estado no se especifica en ningún RFC, pero los proxies HTTP de Microsoft Corp. lo utilizan para indicar un tiempo de espera de conexión de red detrás del proxy a un cliente frente al proxy.

Utilizo el código de estado personalizado 599 para un tiempo de espera de sesión y luego lo verifico en la respuesta de AJAX.

Dermot Doherty
fuente
3
Un tiempo de espera de conexión de red es muy diferente de un tiempo de espera de sesión. Si va a usar un código de una extensión de Microsoft, ¿por qué no usarlo 440 Login Timeout (Microsoft)según la respuesta de Faisal Mq?
toxalot
Esa página de Wikipedia sobre 599 estaba equivocada y no tenía citas. Al parecer, solía decir que los proxies de Microsoft generan 599 en el tiempo de espera de la red, pero tampoco pude encontrar ninguna evidencia de eso.
Gareth Davidson
11

Según el enlace de Wikipedia de los códigos de estado Http proporcionados anteriormente por Bobo:

440 Login Timeout (Microsoft)

    A Microsoft extension. Indicates that your session has expired.
Faisal Mq
fuente
Se dan cuenta de Apache puede convertir ese estado de retorno a 500, como el mío - stackoverflow.com/questions/17735514/...
commonpike
Me gusta esta solución para entornos ASP.NET.
TroySteven
9

Al publicar un enlace, en ese enlace encontré este código de estado HTTP 440 . puede utilizar el código de estado HTTP 440 para la sesión caducada.

440 Tiempo de espera de inicio de sesión

 The client's session has expired and must log in again.

401 No autorizado, podemos usarlo cuando la credencial de inicio de sesión del usuario es incorrecta. o el token de autenticación pasado en el encabezado no es válido.

403 Prohibido, podemos usar esto cuando el usuario no tiene un permiso específico para el recurso solicitado.

Entonces, en mi opinión, deberíamos usar 440 Login Time-out .

Vinay Pandya
fuente
2

Técnicamente, la respuesta aceptada es, por supuesto, correcta: si ya sabe con certeza que va a fallar la solicitud y está preguntando qué código de falla devolver, entonces HTTP 401 "No autorizado (no autenticado)" es el apropiado, para solicitar una nueva autenticación.

Pero antes que nada, pregúntate: debería rechazar la solicitud?

Tenga en cuenta que el usuario puede simplemente estar visitando una página pública de su sitio web, en cuyo caso le va a dar una bofetada en la cara con un "¡No autorizado!" mensaje y exigirles que se vuelvan a autenticar para ver una página que normalmente podrían ver sin autenticación. Eso no es cool.

Mi consejo es ignorar el hecho de que el token de sesión es desconocido y simplemente proceder a generar un nuevo token de sesión y crear una nueva sesión para él. El estado inicial de la sesión, por supuesto, será "aún no autenticado", por lo que si el usuario está intentando acceder a una página no pública, la página se encargará de que reciba un HTTP 401 "No autorizado (no autenticado) "y debe autenticarse. Pero si el usuario llega a una página pública, no notará nada diferente.

Mike Nakis
fuente
0

Usaría una respuesta de redirección 302, con un encabezado de "Ubicación" que dirija a una ruta de recursos como "/ auth-required"

El cliente podría enrutar la ruta del recurso a un modal con un formulario de inicio de sesión / contraseña, evitando transferir al usuario a otra página.

pinei
fuente
-3

Para las solicitudes que no son Ajax, utilizo una redirección 302.

Para las solicitudes de Ajax, utilizo 200 para errores conocidos . De esa forma puedo aprovechar el objeto de datos. Encuentro que el objeto de datos es más fácil de trabajar que analizar jqXHR para obtener información. Y luego no necesito preocuparme por qué código de estado HTTP intentar reutilizar para mi situación.

Ejemplo de jQuery:

$.ajax({
    //send data to server
})
.done(function(data, textStatus, jqXHR) {
    if (data.success) {
        //then process return data
    }
    else {
        //get error type or message from data object
        //could use custom error codes
    }
})
.fail(function(jqXHR, textStatus, errorThrown) {
    //handle unknown errors
});
Toxalot
fuente
6
No querer analizar la respuesta no es una buena razón para desviarse de la especificación HTTP, especialmente cuando solo puede JSON.parse (responseText).
David Nelson
No creo que el uso de un código de respuesta 200 se desvíe de la especificación HTTP en este caso porque la solicitud fue técnicamente exitosa en la capa de transporte. Para mí, los tiempos de espera de la sesión son similares a los errores de formulario en los que devuelvo un mensaje de error fácil de usar. Los desacuerdos expresados ​​en las respuestas a esta pregunta indican claramente que la especificación HTTP no proporciona un código de respuesta aceptado por la industria para tiempos de espera de sesión. ¿Cómo puede uno desviarse de una especificación que no existe?
Toxalot
-4

Código 408. "Solicitar tiempo de espera", parece perfecto: RFC 2616 explica que significa

El cliente no produjo una solicitud dentro del tiempo que el servidor estaba preparado para esperar.

es decir, exactamente un "tiempo muerto", ¡tal como lo necesita!

Alex Martelli
fuente
4
Ah, pero observe el resto de la definición: "El cliente puede repetir la solicitud sin modificaciones en cualquier momento posterior". "Sin modificaciones" implicaría que se podría crear una nueva sesión simplemente recargando / actualizando la solicitud. En la mayoría de los casos, cuando se utiliza la autenticación, el usuario debería volver a iniciar sesión primero.
AJ.
@AJ, por supuesto, la solicitud repetida puede encontrarse con un desafío de autenticación (código HTTP 401); no veo nada en las especificaciones HTTP que prohíban eso , ¿puede señalar algo?
Alex Martelli
5
408 le dice al cliente que debería intentar volver a enviar la solicitud tal como está, lo que obviamente no puede funcionar si la sesión ha expirado.
Tim Post
4
408 es un tiempo de espera de "solicitud", no de sesión. Es decir, el enchufe se estableció pero estaba tardando demasiado. Este sitio hace un buen trabajo explicándolo: checkupdown.com/status/E408.html
Brad Cupit