¿Las sesiones realmente violan el DESCANSO?

¿El uso de sesiones en una API RESTful realmente infringe la RESTfulness? He visto muchas opiniones en ambas direcciones, pero no estoy convencido de que las sesiones sean Inquieto. Desde mi punto de vista:

  • la autenticación no está prohibida para RESTfulness (de lo contrario, habría poco uso en los servicios RESTful)
  • La autenticación se realiza enviando un token de autenticación en la solicitud, generalmente el encabezado
  • este token de autenticación debe obtenerse de alguna manera y puede revocarse, en cuyo caso debe renovarse
  • el token de autenticación debe ser validado por el servidor (de lo contrario, no sería autenticación)

Entonces, ¿cómo violan esto las sesiones?

  • del lado del cliente, las sesiones se realizan mediante cookies
  • las cookies son simplemente un encabezado HTTP adicional
  • una cookie de sesión se puede obtener y revocar en cualquier momento
  • Las cookies de sesión pueden tener una vida útil infinita si es necesario.
  • el ID de sesión (token de autenticación) se valida en el lado del servidor

Como tal, para el cliente, una cookie de sesión es exactamente igual que cualquier otro mecanismo de autenticación basado en encabezados HTTP, excepto que utiliza el Cookie encabezado en lugar del Authorization o algún otro encabezado propietario. Si no hubiera una sesión adjunta al valor de la cookie en el lado del servidor, ¿por qué haría eso la diferencia? La implementación del lado del servidor no tiene por qué preocupar al cliente siempre que el servidor se comporta Sosegado. Como tal, las cookies por sí mismas no deberían hacer una API Inquieto, y las sesiones son simplemente cookies para el cliente.

¿Mis suposiciones son incorrectas? Que hace que las cookies de sesión Inquieto?

preguntado el 20 de mayo de 11 a las 03:05

Para agregar a eso, si solo está usando la sesión para la autenticación, ¿por qué no usar los encabezados proporcionados? Si no es así, y estás usando la sesión para otro estado de la conversación, eso está violando la restricción sin estado de REST. -

@Will Gracias. Parece que estás hablando de sesiones para almacenar temporalmente los datos enviados por el usuario, mientras que en mi caso solo estoy hablando de ellas como un detalle de implementación para la autenticación. ¿Podría ser de aquí de donde proviene el desacuerdo? -

@deceze Mi único punto es que si va a utilizar un encabezado para representar un token de autenticación, HTTP proporciona uno más allá de una cookie genérica. Entonces, ¿por qué no usar eso y mantener la semántica gratuita que obtiene con él (cualquiera que vea la carga útil puede ver que hay un token de autenticación asignado)? -

Claro, pero entonces ¿por qué no inventa sus propios encabezados o secuestra otro encabezado para el token de autenticación? Utilice el encabezado X-XYZZY. Es solo sintaxis, ¿verdad? Los encabezados transmiten información. El encabezado Authorization es más "autodocumentado" que su cookie, porque "todos" saben para qué sirve el encabezado Auth. Si solo ven JSESSIONID (o lo que sea), no pueden hacer suposiciones, o peor aún, hacer suposiciones incorrectas (qué más está almacenando en la sesión, para qué más se usa esto, etc.). ¿Nombra sus variables en su código Aq12hsg? No claro que no. Lo mismo se aplica aquí. -

8 Respuestas

Primero, definamos algunos términos:

  • Sosegado:

    Se pueden caracterizar las aplicaciones que cumplen con las restricciones REST descritas en esta sección como "RESTful". [15] Si un servicio viola alguna de las restricciones requeridas, no se puede considerar RESTful.

    según Wikipedia.

  • restricción sin estado:

    A continuación, agregamos una restricción a la interacción cliente-servidor: la comunicación debe ser de naturaleza sin estado, como en el estilo cliente-servidor-sin estado (CSS) de la Sección 3.4.3 (Figura 5-3), de modo que cada solicitud del cliente al El servidor debe contener toda la información necesaria para comprender la solicitud y no puede aprovechar ningún contexto almacenado en el servidor. Por lo tanto, el estado de la sesión se mantiene completamente en el cliente.

    de acuerdo con la Disertación de campo.

Entonces, las sesiones del lado del servidor violan la restricción sin estado de REST y, por lo tanto, RESTfulness tampoco.

Como tal, para el cliente, una cookie de sesión es exactamente igual que cualquier otro mecanismo de autenticación basado en el encabezado HTTP, excepto que utiliza el encabezado Cookie en lugar de la Autorización o algún otro encabezado propietario.

Mediante las cookies de sesión, almacena el estado del cliente en el servidor y, por lo tanto, su solicitud tiene un contexto. Intentemos agregar un equilibrador de carga y otra instancia de servicio a su sistema. En este caso, debe compartir las sesiones entre las instancias de servicio. Es difícil mantener y ampliar un sistema de este tipo, por lo que escala mal ...

En mi opinión, las cookies no tienen nada de malo. La tecnología de cookies es un mecanismo de almacenamiento del lado del cliente en el que los datos almacenados se adjuntan automáticamente a los encabezados de las cookies por cada solicitud. No conozco una restricción REST que tenga problemas con ese tipo de tecnología. Así que no hay problema con la tecnología en sí, el problema está en su uso. Fielding escribió una subsección sobre por qué cree que las cookies HTTP son malas.

Desde mi punto de vista:

  • la autenticación no está prohibida para RESTfulness (de lo contrario, habría poco uso en los servicios RESTful)
  • La autenticación se realiza enviando un token de autenticación en la solicitud, generalmente el encabezado
  • este token de autenticación debe obtenerse de alguna manera y puede revocarse, en cuyo caso debe renovarse
  • el token de autenticación debe ser validado por el servidor (de lo contrario, no sería autenticación)

Tu punto de vista fue bastante sólido. El único problema fue con el concepto de crear un token de autenticación en el servidor. No necesitas esa parte. Lo que necesita es almacenar el nombre de usuario y la contraseña en el cliente y enviarlos con cada solicitud. No necesita más para hacer esto que la autenticación básica HTTP y una conexión encriptada:

Figura 1. - Autenticación sin estado por parte de clientes confiables

  • Figura 1. - Autenticación sin estado por parte de clientes confiables

Probablemente necesite una caché de autenticación en memoria en el lado del servidor para agilizar las cosas, ya que debe autenticar cada solicitud.

Ahora bien, esto funciona bastante bien por clientes de confianza escritos por usted, pero ¿qué pasa con los clientes de terceros? No pueden tener el nombre de usuario y la contraseña y todos los permisos de los usuarios. Por lo tanto, debe almacenar por separado qué permisos puede tener un cliente de terceros para un usuario específico. Por lo tanto, los desarrolladores de clientes pueden registrar sus clientes de terceros y obtener una clave API única y los usuarios pueden permitir que los clientes de terceros accedan a una parte de sus permisos. Como leer el nombre y la dirección de correo electrónico, o enumerar a sus amigos, etc. Después de permitir un cliente de terceros, el servidor generará un token de acceso. Este token de acceso puede ser utilizado por el cliente de terceros para acceder a los permisos otorgados por el usuario, así:

Figura 2. - Autenticación sin estado por clientes de terceros

  • Figura 2. - Autenticación sin estado por clientes de terceros

Entonces, el cliente de terceros puede obtener el token de acceso de un cliente confiable (o directamente del usuario). Después de eso, puede enviar una solicitud válida con la clave API y el token de acceso. Este es el mecanismo de autenticación de terceros más básico. Puede leer más sobre los detalles de implementación en la documentación de cada sistema de autenticación de terceros, por ejemplo, OAuth. Por supuesto, esto puede ser más complejo y más seguro, por ejemplo, puede firmar los detalles de cada solicitud en el lado del servidor y enviar la firma junto con la solicitud, y así sucesivamente ... La solución real depende de la necesidad de su aplicación.

Respondido el 25 de enero de 15 a las 13:01

Sí, tienes toda la razón. Desde que publiqué esta pregunta, me he dado cuenta de eso. Las cookies de sesión no son nada especial cuando se miran en los detalles técnicos, pero eso es lo que le falta al bosque para los árboles. Acepté tu respuesta por los agradables gráficos. ;) - deceze ♦

Ok, lo repensé, la respuesta del servicio REST no debería depender de la autorización, entonces creo que las 2 primeras soluciones están 100% bien, y las otras están bien si el servicio usa la información solo para decidir si permite la solicitud o no. Entonces creo que los permisos de usuario deberían afectar la representación del recurso actual. - inf3rno

Crearé una pregunta sobre la dependencia de permisos de las representaciones. Extenderé esta respuesta tan pronto como tenga la solución adecuada. - inf3rno

@ inf3rno, es cierto que un servicio completamente RESTful no puede depender de las cookies de sesión para la autenticación en la forma en que se implementa tradicionalmente. Sin embargo, puede utilizar cookies para realizar la autenticación si la cookie contiene toda la información de estado que el servidor necesitará más adelante. También puede hacer que la cookie no sea manipulada firmándola con un par de claves pública / privada. Vea mis comentarios a continuación. - jcoffland

No entiendo por qué todo el mundo parece aceptar el comentario, debería almacenar las contraseñas del lado del cliente y enviarlas con cada solicitud. Esta es una práctica muy mala y pone en peligro los datos confidenciales de sus clientes. Una contraseña sin hash (que tendría que ser para enviarla una y otra vez) nunca debe almacenarse en ningún lugar. Si aceptamos esto, entonces está usando tokens como lo hacen la mayoría de los sistemas de autenticación, en cuyo caso cualquier mecanismo que usemos para escalar el repositorio de tokens tendrá preocupaciones de escalabilidad en su mayoría iguales a las de cualquier escala de sesión. - lvoelk

En primer lugar, REST no es una religión y no debe abordarse como tal. Si bien los servicios RESTful tienen ventajas, solo debe seguir los principios de REST en la medida en que tengan sentido para su aplicación.

Dicho esto, la autenticación y el estado del lado del cliente no violan los principios REST. Si bien REST requiere que las transiciones de estado sean sin estado, esto se refiere al servidor en sí. En el fondo, todo REST se trata de documentos. La idea detrás de la apatridia es que el SERVIDOR es apátrida, no los clientes. Cualquier cliente que emita una solicitud idéntica (los mismos encabezados, cookies, URI, etc.) debe ser llevado al mismo lugar en la aplicación. Si el sitio web almacena la ubicación actual del usuario y gestiona la navegación actualizando esta variable de navegación del lado del servidor, se infringiría REST. Otro cliente con información de solicitud idéntica sería llevado a una ubicación diferente según el estado del lado del servidor.

Los servicios web de Google son un ejemplo fantástico de un sistema RESTful. Requieren un encabezado de autenticación con la clave de autenticación del usuario que se transmite en cada solicitud. Esto viola levemente los principios REST, porque el servidor está rastreando el estado de la clave de autenticación. El estado de esta clave debe mantenerse y tiene algún tipo de fecha / hora de vencimiento después de la cual ya no otorga acceso. Sin embargo, como mencioné en la parte superior de mi publicación, se deben hacer sacrificios para permitir que una aplicación funcione realmente. Dicho esto, los tokens de autenticación deben almacenarse de una manera que permita a todos los clientes posibles continuar otorgando acceso durante sus tiempos válidos. Si un servidor está administrando el estado de la clave de autenticación hasta el punto de que otro servidor con equilibrio de carga no puede hacerse cargo de cumplir con las solicitudes basadas en esa clave, realmente ha comenzado a violar los principios de REST. Los servicios de Google garantizan que, en cualquier momento, pueda tomar un token de autenticación que estaba usando en su teléfono contra el servidor de equilibrio de carga A y acceder al servidor de equilibrio de carga B desde su escritorio y seguir teniendo acceso al sistema y ser dirigido a los mismos recursos si las solicitudes fueron idénticas.

Todo se reduce a que debe asegurarse de que sus tokens de autenticación estén validados con un almacén de respaldo de algún tipo (base de datos, caché, lo que sea) para asegurarse de preservar la mayor cantidad posible de propiedades REST.

Espero que todo eso tenga sentido. También debería consultar el Sección de restricciones de los artículo de wikipedia sobre transferencia de estado representacional si aún no lo ha hecho. Es particularmente esclarecedor con respecto a lo que realmente defienden los principios de REST y por qué.

respondido 24 nov., 14:00

Reformularía su declaración inicial. Solo use REST si las restricciones de REST tienen sentido para su aplicación. Puede aplicar un subconjunto de esas restricciones y obtendrá un subconjunto de los beneficios. Sin embargo, en ese momento ha creado su propio estilo arquitectónico. Sin embargo, eso no es malo, de hecho, de eso se tratan los primeros cuatro capítulos de la disertación de Roy, el diseño basado en principios. REST fue solo un ejemplo. - darrel molinero

@Jared ¿Estás seguro de que el token de autenticación de Google no tiene codificada la fecha de caducidad? No parece que sea difícil de hacer dos. - darrel molinero

@Darrel Un punto bastante justo. Honestamente, no estoy seguro de cómo lo hace Google, pero el tiempo de vencimiento podría estar codificado en el token de autenticación. Sin embargo, creo que mi punto más importante sigue en pie. Hay algunos tipos de estado que simplemente deben mantenerse y siempre que usted comprenda el porqué REST exige la apatridia, puede violarlo de una manera que tenga sentido sin muchas repercusiones en el resto del sistema y las ventajas de una arquitectura RESTful. - jared harding

Dado que hasta ahora no se han presentado otros argumentos, acepto esta respuesta bien escrita. Creo que la parte importante es que servidor sin estado no quiere decir servidor sin estado, algo que creo que a menudo se malinterpreta o se aplica mal. El servidor puede (y generalmente debe:) tiene el estado que quiera, siempre que se comporte idempotente. - deceze ♦

He escuchado tanta predicación que las sesiones no son relajantes. Sin embargo, la autenticación básica HTTP es un paso atrás real si está tratando de crear una aplicación web. - ben thurley

Las cookies no son para autenticación. ¿Por qué reinventar una rueda? HTTP tiene mecanismos de autenticación bien diseñados. Si usamos cookies, usamos HTTP solo como protocolo de transporte, por lo que necesitamos crear nuestro es dueño sistema de señalización, por ejemplo, para decirles a los usuarios que proporcionaron una autenticación incorrecta (usar HTTP 401 sería incorrecto ya que probablemente no proporcionaríamos Www-Authenticate a un cliente, como requieren las especificaciones HTTP :)). También debe tenerse en cuenta que Set-Cookie es solo una recomendación para el cliente. Su contenido puede guardarse o no (por ejemplo, si las cookies están deshabilitadas), mientras Authorization El encabezado se envía automáticamente en cada solicitud.

Otro punto es que, para obtener una cookie de autorización, probablemente querrá proporcionar primero sus credenciales en algún lugar. Si es así, ¿no sería RESTless? Ejemplo simple:

  • Lo intentas GET /a sin galleta
  • Obtienes una solicitud de autorización de alguna manera
  • Vas y autorizas de alguna manera como POST /auth
  • Usted obtiene Set-Cookie
  • Lo intentas GET /a con Galleta. Pero lo hace GET /a comportarse idempotentemente en este caso?

En resumen, creo que si accedemos a algún recurso y necesitamos autenticarnos, entonces debemos autenticarnos. en ese mismo recurso, no en ningún otro lugar.

Respondido el 24 de enero de 13 a las 10:01

Mientras tanto, también me acerqué más a este punto de vista. Creo que técnicamente hace poca diferencia, son solo encabezados HTTP. Aunque es cierto que el comportamiento de autenticación en sí mismo no es RESTful, si se requiere iniciar sesión a través de una dirección separada. Por lo tanto, las cookies son solo un síntoma de un problema mayor con el sistema de autenticación. - deceze ♦

Esto realmente no tiene en cuenta el hecho de que los navegadores web solo admiten Authorization: Basic or Digest. Si desea hacer algo más avanzado que la autenticación básica o resumida (y debería hacerlo) en un contexto de navegador, entonces necesitará algo más que el Authorization encabezamiento. - Oliver Charlesworth

Absolutamente, si está haciendo JS puro, las cosas están básicamente bien (excepto, por ejemplo, Websockets). Pero mi punto es que la autenticación basada en API no es necesariamente la única consideración en un escenario de navegador. - Oliver Charlesworth

GET /a sin una cookie y con una cookie son claramente dos una experiencia diferente solicitudes, y es aceptable que se comporten de manera diferente. - Trigonometría

Para agregar a @TRiG, ​​siguiendo esta lógica, GET /a con encabezado de autenticación también es el mismo que GET /a sin el encabezado de autenticación, por lo que es igualmente inutilizable para REST. Si va a tratar un encabezado http de manera diferente a otro, lo abordará como mínimo. - Jaspe

En realidad, DESCANSO solo se aplica a RECURSOS, como lo indica un Identificador de recurso universal. Entonces, incluso hablar sobre cosas como encabezados, cookies, etc. en lo que respecta a REST no es realmente apropiado. REST puede funcionar con cualquier protocolo, aunque se haga de forma rutinaria a través de HTTP.

El determinante principal es este: si envía una llamada REST, que es un URI, una vez que la llamada llega con éxito al servidor, ese URI devuelve el mismo contenido, asumiendo que no se han realizado transiciones (PUT, POST, DELETE) ? Esta prueba excluiría los errores o las solicitudes de autenticación que se devuelven, porque en ese caso, la solicitud aún no ha llegado al servidor, es decir, el servlet o la aplicación que devolverá el documento correspondiente al URI dado.

Del mismo modo, en el caso de un POST o PUT, ¿puede enviar un URI / payload determinado e independientemente de cuántas veces envíe el mensaje, siempre actualizará los mismos datos, de modo que los GET posteriores devolverán un resultado coherente?

REST se trata de los datos de la aplicación, no de la información de bajo nivel necesaria para transferir esos datos.

En la siguiente publicación del blog, Roy Fielding dio un buen resumen de toda la idea de REST:

http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841

"Un sistema RESTful progresa de un estado estable al siguiente, y cada uno de esos estados estacionarios es tanto un estado inicial potencial como un estado final potencial. Es decir, un sistema REST es un número desconocido de componentes que obedecen a un conjunto simple de reglas tales que siempre están en REST o en transición de un estado REST a otro estado RESTful. Cada estado puede entenderse completamente por las representaciones que contiene y el conjunto de transiciones que proporciona, con las transiciones limitadas a un estado uniforme. conjunto de acciones para que sea comprensible. El sistema puede ser un diagrama de estado complejo, pero cada agente de usuario solo puede ver un estado a la vez (el estado estable actual) y, por lo tanto, cada estado es simple y se puede analizar de forma independiente. el usuario, OTOH, puede crear sus propias transiciones en cualquier momento (por ejemplo, ingresar una URL, seleccionar un marcador, abrir un editor, etc.) ".


Pasando al tema de la autenticación, ya sea que se realice a través de cookies o encabezados, siempre que la información no sea parte de la carga útil URI y POST, realmente no tiene nada que ver con REST. Entonces, en lo que respecta a ser apátrida, estamos hablando solo de los datos de la aplicación.

Por ejemplo, cuando el usuario ingresa datos en una pantalla GUI, el cliente realiza un seguimiento de los campos que se ingresaron, los que no, los campos obligatorios que faltan, etc. Todo esto es CONTEXTO DEL CLIENTE, y no debe enviarse ni rastrearse. por el servidor. Lo que sí se envía al servidor es el conjunto completo de campos que necesitan ser modificados en el recurso IDENTIFICADO (por el URI), de modo que ocurra una transición en ese recurso de un estado RESTful a otro.

Por lo tanto, el cliente realiza un seguimiento de lo que está haciendo el usuario y solo envía transiciones de estado lógicamente completas al servidor.

Respondido 22 Feb 14, 00:02

No veo cómo esto arroje luz sobre la pregunta planteada. - jcoffland

La transacción HTTP, autenticación de acceso básico, no es adecuada para RBAC, porque la autenticación de acceso básica usa el nombre de usuario cifrado: contraseña cada vez para identificar, mientras que lo que se necesita en RBAC es el rol que el usuario desea usar para una llamada específica. RBAC no valida los permisos de nombre de usuario, sino de roles.

Podría intentar concatenar así: usernameRole: password, pero esta es una mala práctica y también es ineficiente porque cuando un usuario tiene más roles, el motor de autenticación necesitaría probar todos los roles en la concatenación, y cada llamada nuevamente. Esto destruiría una de las mayores ventajas técnicas de RBAC, a saber, una prueba de autorización muy rápida.

De modo que ese problema no se puede resolver mediante la autenticación de acceso básica.

Para resolver este problema, es necesario el mantenimiento de sesiones, y eso parece, según algunas respuestas, en contradicción con REST.

Eso es lo que me gusta de la respuesta de que el REST no debe tratarse como una religión. En casos comerciales complejos, en la atención médica, por ejemplo, RBAC es absolutamente común y necesario. Y sería una pena que no se les permitiera usar REST porque todos los diseñadores de herramientas REST tratarían a REST como una religión.

Para mí, no hay muchas formas de mantener una sesión a través de HTTP. Se pueden usar cookies, con un sessionId, o un encabezado con un sessionId.

Si alguien tiene otra idea, me alegrará escucharla.

Respondido el 16 de junio de 15 a las 10:06

Creo que el token debe incluir toda la información necesaria codificada en su interior, lo que hace la autenticación validando el token y decodificando la información. https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

contestado el 17 de mayo de 20 a las 04:05

No, el uso de sesiones no necesariamente infringe el RESTfulness. Si se adhiere a los preceptos y restricciones de REST, entonces usar sesiones, para mantener el estado, será simplemente superfluo. Después de todo, RESTfulness requiere que el servidor no mantenga el estado.

Respondido el 30 de diciembre de 20 a las 09:12

En mi opinión, la mayoría de las respuestas malinterpretan lo que significa que una API sea RESTful. Una API RESTful satisface las restricciones REST: interfaz uniforme, sin estado, almacenable en caché, cliente-servidor, sistema en capas, código a pedido. Es muy posible que su API implemente sesiones mientras satisface estas restricciones. - user14699123

  1. Las sesiones no son sin descanso
  2. ¿Quiere decir que el servicio REST es solo para uso http o me equivoqué? La sesión basada en cookies debe usarse solo para servicios propios (!) Basados ​​en http. (Podría ser un problema trabajar con cookies, por ejemplo, desde el dispositivo móvil / consola / escritorio / etc.)
  3. Si proporciona un servicio RESTful para desarrolladores de terceros, nunca use sesiones basadas en cookies, use tokens en su lugar para evitar problemas de seguridad.

contestado el 20 de mayo de 11 a las 07:05

la cookie no debe usarse para almacenar una clave de sesión para una sesión en el servidor que contiene el token de autenticación. pero si la cookie contiene el token de autenticación en sí, es una solución factible. (por supuesto, la cookie debe ser de forma directa y segura) - roberkules

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.