¿Usar sesiones en una API RESTful realmente viola 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 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 las sesiones esto?
- del lado del cliente, las sesiones se realizan con cookies
- las cookies son simplemente un encabezado HTTP adicional
- Se puede obtener y revocar una cookie de sesión 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 la misma que cualquier otro mecanismo de autenticación basado en encabezado HTTP, excepto que usa el Cookie
encabezado en lugar del Authorization
u otro encabezado propietario. Si no hubo una sesión adjunta al valor del cookie en el lado del servidor, ¿por qué eso marcaría la diferencia? La implementación del lado del servidor no necesita preocupar al cliente siempre que el servidor se comporte RESTful. Como tal, las cookies por sí mismas no deberían hacer que una API RESTless , y las sesiones son simplemente cookies para el cliente.
¿Están equivocados mis supuestos? ¿Qué hace que las cookies de sesión sean RESTless ?
fuente
Respuestas:
Primero, definamos algunos términos:
Sosegado:
de acuerdo con wikipedia .
restricción sin estado:
de acuerdo con la tesis de Fielding .
Entonces, las sesiones del lado del servidor violan la restricción sin estado de REST, y también RESTfulness.
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 extender dicho sistema, por lo que se escala mal ...
En mi opinión, no hay nada 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 cookies por cada solicitud. No sé de una restricción REST que tenga problemas con ese tipo de tecnología. Por lo tanto, no hay problema con la tecnología en sí, el problema está en su uso. Fielding escribió una subsección sobre por qué piensa que las cookies HTTP son malas.
Tu punto de vista era bastante sólido. El único problema fue con el concepto de crear 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 enviarlo con cada solicitud. No necesita más para hacer esto que la autenticación básica HTTP y una conexión cifrada:
Probablemente necesite un caché de autenticación en memoria en el lado del servidor para acelerar las cosas, ya que debe autenticar cada solicitud.
Ahora 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 por parte de 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 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. Estos tokens de acceso pueden ser utilizados por el cliente de terceros para acceder a los permisos otorgados por el usuario, así:
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 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.
fuente
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 no tengan 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 no tiene estado, no los clientes. Cualquier cliente que emita una solicitud idéntica (mismos encabezados, cookies, URI, etc.) debe ser llevado al mismo lugar en la aplicación. Si el sitio web almacenó la ubicación actual del usuario y administró la navegación actualizando esta variable de navegación del lado del servidor, se violaría REST. Otro cliente con información de solicitud idéntica sería llevado 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 que se envíe un encabezado de autenticación con la clave de autenticación del usuario a cada solicitud. Esto viola ligeramente 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 realmente funcione. 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 administra 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, has 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 solicitudes fueron idénticas.
Todo se reduce a que debe asegurarse de que sus tokens de autenticación estén validados contra un almacén de respaldo de algún tipo (base de datos, caché, lo que sea) para garantizar que conserve 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 sobre Transferencia de estado representacional si aún no lo ha hecho. Es particularmente esclarecedor con respecto a lo que los principios de REST realmente defienden y por qué.
fuente
Las cookies no son para autenticación. ¿Por qué reinventar una rueda? HTTP tiene mecanismos de autenticación bien diseñados. Si usamos cookies, caemos en el uso de HTTP solo como protocolo de transporte, por lo tanto, necesitamos crear nuestro propio 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 lo haríamos). suministro
Www-Authenticate
a un cliente, ya que las especificaciones HTTP requieren :)). También debe tenerse en cuenta queSet-Cookie
es solo una recomendación para el cliente. Su contenido puede guardarse o no (por ejemplo, si las cookies están deshabilitadas), mientrasAuthorization
encabezado 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? Si es así, ¿no sería RESTless? Ejemplo simple:
GET /a
sin cookiePOST /auth
Set-Cookie
GET /a
con galleta. ¿Pero seGET /a
comporta de manera idempotente en este caso?Para resumir esto, creo que si accedemos a algún recurso y necesitamos autenticarnos, entonces debemos autenticarnos en ese mismo recurso , no en ningún otro lugar.
fuente
Authorization: Basic
oDigest
. Si desea hacer algo más avanzado que la autenticación básica o de resumen (y debería hacerlo) en un contexto de navegador, necesitará algo más que elAuthorization
encabezado.GET /a
sin una cookie y con una cookie son claramente dos solicitudes diferentes , y es aceptable que se comporten de manera diferente.GET /a
con el encabezado de autenticación también es lo mismo queGET /a
sin el encabezado de autenticación, lo que lo hace igualmente inutilizable para REST. Si va a tratar un encabezado http de manera diferente a otro, al menos lo abordará.En realidad, RESTfulness solo se aplica a los RECURSOS, como lo indica un Identificador Universal de Recursos. Por lo tanto, incluso hablar de cosas como encabezados, cookies, etc. con respecto a REST no es realmente apropiado. REST puede funcionar sobre cualquier protocolo, a pesar de que se realiza rutinariamente a través de HTTP.
El principal determinante es este: si envía una llamada REST, que es un URI, una vez que la llamada se realiza con éxito al servidor, ese URI devuelve el mismo contenido, suponiendo que no se hayan realizado transiciones (PUT, POST, DELETE) ? Esta prueba excluiría errores o 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 dado.
Del mismo modo, en el caso de un POST o PUT, ¿puede enviar un URI / carga útil dado, e independientemente de cuántas veces envíe el mensaje, siempre actualizará los mismos datos, de modo que los GET posteriores arrojarán un resultado consistente?
REST trata 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 de 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 progresa de un estado estable al siguiente, y cada uno de estos estados estables es tanto un estado inicial 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 RESTful. Cada estado puede ser completamente entendido por la (s) representación (es) que contiene y el conjunto de transiciones que proporciona, con las transiciones limitadas a un 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, ingrese una URL, seleccione un marcador,abrir un editor, etc.) ".
En cuanto 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 de 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, a medida que 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. 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.
fuente
La transacción HTTP, autenticación de acceso básico, no es adecuada para RBAC, porque la autenticación de acceso básico 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 permisos en nombre de usuario, sino en roles.
Podría dar vueltas para concatenar de esta manera: 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, es decir, una prueba de autorización muy rápida.
Por lo tanto, ese problema no se puede resolver con la autenticación de acceso básica.
Para resolver este problema, es necesario mantener la sesión y, según algunas respuestas, parece estar en contradicción con REST.
Eso es lo que me gusta de la respuesta de que REST no debe tratarse como una religión. En casos de negocios complejos, en el cuidado de la 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 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 Id. De sesión, o un encabezado con un Id. De sesión.
Si alguien tiene otra idea, me alegrará escucharla.
fuente
Creo que el token debe incluir toda la información necesaria codificada dentro de él, lo que hace que la autenticación valide el token y decodifique la información https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/
fuente
fuente