example session rest cookies restful-authentication

session - example - ¿Las sesiones realmente violan RESTfulness?



rest api header authentication (6)

  1. Las sesiones no son RESTless
  2. ¿Quiere decir que el servicio REST solo para uso de http o me equivoco un poco? ¡La sesión basada en cookies se debe utilizar solo para los servicios basados ​​en http (!) Propios! (Podría ser un problema trabajar con cookies, por ejemplo, desde Mobile / Console / Desktop / etc.)
  3. Si proporciona un servicio REST para los desarrolladores de terceros, nunca use una sesión basada en cookies, use tokens para evitar los problemas de seguridad.

¿El uso de sesiones en una API RESTful realmente está violando a RESTfulness? He visto muchas opiniones en cualquier dirección, pero no estoy convencido de que las sesiones sean RESTless . 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 mediante el envío de un token de autenticación en la solicitud, generalmente el encabezado
  • este token de autenticación debe obtenerse de alguna manera y puede ser revocado, 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 las sesiones violan esto?

  • del lado del cliente, las sesiones se realizan utilizando 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 un tiempo de vida infinito si es necesario.
  • el id de sesión (token de autenticación) se valida del lado del servidor

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

¿Están mis suposiciones equivocadas? ¿Qué hace que las cookies de sesión sean RESTless ?


En primer lugar, REST no es una religión y no debe abordarse como tal. Si bien los servicios RESTful ofrecen 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. Mientras que REST requiere que las transiciones de estado sean sin estado, esto se refiere al servidor en sí. En el corazón, todo REST es sobre 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 almacenaba la ubicación actual del usuario y la navegación administrada al actualizar esta variable de navegación del lado del servidor, se violaría REST. Otro cliente con información de solicitud idéntica se llevaría a una ubicación diferente dependiendo del 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 para pasar cada solicitud. Esto viola ligeramente los principios de 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 caducidad 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 realmente funcione. Dicho esto, los tokens de autenticación deben almacenarse de una manera que permita a todos los posibles clientes 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 carga equilibrada no puede asumir el cumplimiento de las solicitudes basadas en esa clave, usted ha comenzado a violar realmente los principios de REST. Los servicios de Google aseguran que, en cualquier momento, puede tomar un token de autenticación que estaba usando en su teléfono contra el servidor de equilibrio de carga A y golpear el servidor de equilibrio de carga B desde su escritorio y aún tener acceso al sistema y ser dirigido a los mismos recursos si Las peticiones eran idénticas.

Todo se reduce a que es necesario asegurarse de que sus tokens de autenticación se validen contra un almacén de respaldo de algún tipo (base de datos, caché, lo que sea) para garantizar que conserva la mayor cantidad posible de propiedades REST.

Espero que todo eso tenga sentido. También debe consultar la sección Restricciones del artículo de wikipedia si aún no lo ha hecho. Es particularmente esclarecedor con respecto a lo que los principios de REST están defendiendo y por qué.


En realidad, RESTfulness solo se aplica a RECURSOS, como lo indica un Identificador Universal de Recursos. Así que incluso hablar de cosas como encabezados, cookies, etc. en relación con REST no es realmente apropiado. REST puede funcionar con cualquier protocolo, aunque se realice de forma rutinaria a través de HTTP.

El factor determinante principal es este: si envía una llamada REST, que es una URI, entonces una vez que la llamada llega con éxito al servidor, la 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 se ha enviado al servidor, es decir, el servlet o la aplicación que devolverá el documento correspondiente al URI determinado.

Del mismo modo, en el caso de un POST o PUT, ¿puede enviar una URI / carga útil dada, y sin importar cuántas veces envíe el mensaje, siempre se actualizarán los mismos datos, de modo que los GET posteriores devolverán un resultado consistente?

REST es sobre los datos de la aplicación, no sobre la información de bajo nivel requerida para transferir esos datos.

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

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

"Un sistema RESTful avanza de un estado estable a otro, y cada estado estable es tanto un estado de inicio potencial como un estado final potencial. Es decir, un sistema RESTful 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 RESTful a otro estado REST. Cada estado puede ser comprendido completamente por la representación (es) que contiene y el conjunto de transiciones que proporciona, con las transiciones limitadas a un uniforme El sistema puede ser un diagrama de estado complejo, pero cada agente de usuario solo puede ver un estado a la vez (el estado estacionario actual) y, por lo tanto, cada estado es simple y puede analizarse independientemente. El usuario, OTOH, puede crear sus propias transiciones en cualquier momento (por ejemplo, ingresar una URL, seleccionar un marcador, abrir un editor, etc.) ".

Ir a la cuestión 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 de URI y POST, realmente no tiene nada que ver con REST. Por lo tanto, en lo que respecta a ser apátridas, estamos hablando solo de los datos de la aplicación.

Por ejemplo, a medida que el usuario ingresa los datos en una pantalla GUI, el cliente realiza un seguimiento de los campos que se han ingresado, los cuales no tienen, los campos requeridos que faltan, etc. Esto es todo CONTEXTO DEL CLIENTE y no debe enviarse ni rastrearse por el servidor. Lo que se envía al servidor es el conjunto completo de campos que deben modificarse en el recurso IDENTIFICADO (por el URI), de modo que se produzca 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.


La transacción HTTP, la autenticación de acceso básico, no es adecuada para RBAC, porque la autenticación de acceso básica utiliza el nombre de usuario cifrado: contraseña cada vez que se identifica, 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 en el nombre de usuario, sino en los roles.

Se podría tratar de concatenar de esta manera: usernameRole: password, pero esto es una mala práctica, y también es ineficiente porque cuando un usuario tiene más roles, el motor de autenticación debería probar todos los roles en concatenación, y eso es lo que hace 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.

Por lo tanto, ese problema no se puede resolver utilizando la autenticación de acceso básica.

Para resolver este problema, el mantenimiento de la sesión es necesario, y eso parece, de acuerdo con algunas respuestas, en contradicción con REST.

Eso es lo que me gusta de la respuesta de que REST no debe ser tratado como una religión. En casos de negocios complejos, en salud, 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 maneras de mantener una sesión a través de HTTP. Se pueden usar cookies, con un ID de sesión o un encabezado con un Id. De sesión.

Si alguien tiene otra idea, me alegrará escucharla.


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

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

  • Intenta GET /a sin cookie
  • Obtienes una solicitud de autorización de alguna manera
  • Vas y autorizas de alguna manera como POST /auth
  • Obtienes Set-Cookie
  • Intenta GET /a con cookie. Pero, ¿se comporta GET /a idempotentemente en este caso?

Para resumir, creo que si accedemos a algún recurso y necesitamos autenticarlo, debemos autenticarlo en ese mismo recurso , no en ningún otro lugar.


Primero, definamos algunos términos:

  • Sosegado:

    Uno puede caracterizar las aplicaciones que cumplen con las restricciones REST descritas en esta sección como "RESTful". [15] Si un servicio viola cualquiera de las restricciones requeridas, no puede considerarse REST.

    segun wikipedia

  • restricción sin estado:

    A continuación, agregamos una restricción a la interacción cliente-servidor: la comunicación debe ser de carácter sin estado, como en el estilo cliente-sin estado-servidor (CSS) de la Sección 3.4.3 (Figura 5-3), de modo que cada solicitud del cliente a 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 sesión se mantiene enteramente en el cliente.

    Según la disertación de Fielding .

Así que 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 a cualquier otro mecanismo de autenticación basado en encabezado HTTP, excepto que utiliza el encabezado de Cookie en lugar de la Autorización o algún otro encabezado propietario.

Las cookies de sesión almacenan 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 extender un sistema de este tipo, por lo que se escala mal ...

En mi opinión no hay nada de malo con las cookies. 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. Entonces, no hay problema con la tecnología en sí, el problema es con 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 mediante el envío de un token de autenticación en la solicitud, generalmente el encabezado
  • este token de autenticación debe obtenerse de alguna manera y puede ser revocado, 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 cifrada:

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

Probablemente necesite un caché de autenticación en memoria en el lado del servidor para hacer las cosas más rápido, ya que tiene que autenticar cada solicitud.

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

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

Por lo tanto, el cliente de terceros puede obtener el token de acceso de un cliente de confianza (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 individual en el servidor y enviar la firma junto con la solicitud, y así sucesivamente ... La solución real depende de la necesidad de su aplicación.