¿Cómo almacenar en caché los formularios con un proxy inverso y tratar con tokens de formularios obsoletos?

8

Cuando la API de formulario genera un formulario, también genera un token que se pasa con el formulario en un campo oculto y se espera que se devuelva. Si es así, se procesa el formulario.

Si una forma renderizada se almacena en caché, digamos, por Varnish , este mecanismo se rompe. El primer usuario que envíe el formulario consumirá el token, y los siguientes intentos de usar el formulario serán rechazados.

¿Qué estrategias están disponibles para mantener los formularios funcionando mientras almacenan en caché su forma renderizada?

Letharion
fuente
¿Estas seguro acerca de esto? He creado sitios con formularios y servidores proxy inversos y no he visto ningún problema. Lo único que debe ver, en general, es asegurarse de que las páginas de resultados no se almacenen en caché.
Alfred Armstrong
Me encantaría que me demuestren lo contrario, ya que eso resolvería mi problema, pero sí, estoy seguro. :) Verifique las funciones form_ {g, s} et_cache para más detalles.
Letharion
Para usuarios anónimos, estoy seguro de que una página con un formulario se puede almacenar en caché de forma segura. Para los usuarios no anónimos, los servidores proxy inversos son problemáticos en cualquier caso.
Alfred Armstrong
2
(Los tokens solo se generan cuando un usuario tiene una ID.)
Alfred Armstrong
1
Ah, eso tiene sentido. Lamentablemente, mis usuarios en este caso están autenticados. Quizás la pregunta debería reformularse para incluir eso.
Letharion

Respuestas:

5

Yo uso BOA para mis sitios, pero por defecto BOA simplemente deshabilita el almacenamiento en caché frontal sobre la marcha para la presentación de formularios. Más allá de mi experiencia real, me crucé con un artificial de un año sobre cómo el New Zealand Post trata con Drupal & Varnish y el problema del token de formulario. Santo John Wayne, es una lectura obligada para el almacenamiento en caché de Drupal, realmente. Centrándose solo en el problema del formulario:

La pieza final de nuestro rompecabezas es el módulo avanzado de omisión de caché de cookies , que establece automáticamente una cookie NO_CACHE especial cada vez que el usuario envía un formulario POST en el sitio, que incluye elementos como el formulario de inicio de sesión. Nuestro Barniz está configurado para omitir el caché de la página (pero no el caché ESI) cuando ve esta cookie.

También puede deshabilitar los tokens de formulario cuando no se requiere la producción de XSRF en form_alter (unset ($ form ['# token']);) o ($ form ['# token'] = FALSE;)

Un artículo de rendimiento de Acquia Drupal presenta un módulo Drupal Authcache , pero al leer el documento en Authcache, resuelve el almacenamiento en caché con un marcador de posición para el formulario (no almacena en caché el formulario):

Authcache intenta interceptar cualquier contenido personalizado y configurar un marcador de posición dentro del HTML. Luego, después de cargar la página, se utiliza una devolución de llamada Ajax para recuperar datos personalizados y completar los marcadores de posición, actualizando dinámicamente el HTML de la página.

Marcadores de posición de Authcache actuales: tokens de formulario (solo usuarios registrados; requerido por> Drupal para evitar ataques de falsificación de solicitudes entre sitios)

La estrategia es almacenar todo menos el formulario . Entonces abordando todo lo demás: ¿Quizás Varnish no se usa en absoluto, Memcache & Redis? Mi estrategia sería usar lo que ofrece BOA porque uso BOA y los asistentes detrás de él ( omega8.cc ) saben mucho más que yo. No creo que haya un caché externo que resuelva el problema. Todos parecen omitir el formulario.

Realice el almacenamiento en caché parcial con la memoria caché mencionada anteriormente y con vistas y paneles finamente modificados como se menciona en el artículo de NZ Post y se describe por la confianza del cerebro en Wunderkraut : es antiguo, pero aborda el problema.

Use el módulo Drupal ESI y Varnish es parcialmente compatible con ESI):

ESI, o Edge Side incluye, es una solución de almacenamiento en caché de alto rendimiento para usuarios autenticados, pero también puede ser útil para usuarios anónimos.

Por lo general, las páginas personalizadas para usuarios autenticados (incluso personalizaciones menores, como un bloque que dice "Conectado como administrador") evitarán que los servidores proxy inversos (que pueden funcionar fácilmente 100 veces más rápido que Drupal) almacenen en la memoria caché de la página, porque los mensajes destinado a un usuario podría ser visto por otro.

Espero que sea más útil.

Tom
fuente
Un vistazo rápido al código sugiere que el módulo ESI no hace nada en lo que respecta a la validación de formularios; no se menciona el manejo de tokens ni se altera ninguna forma interesante. ¿Es posible que simplemente no haya almacenado en caché ningún formulario que requiera autenticación en barniz, y es por eso que nunca ha visto este problema?
Letharion
Resulta que eso es exactamente lo que está sucediendo, BOA pasa por alto el caché front-end sobre la marcha para los formularios (perdón por mi respuesta previamente incompleta / incorrecta). ESI sigue siendo una parte importante de la estrategia "almacenar todo menos" ahora en mi respuesta, incluso si no se resuelve directamente.
Tom
Ese artículo publicado en Nueva Zelanda fue realmente interesante. Sin embargo, por lo que puedo decir, solo aborda el problema del token con: "En los casos en que esté seguro de que la protección XSRF no es importante ... Drupal proporciona un mecanismo para deshabilitar los tokens de formulario", lo que no es útil en mi caso.
Letharion
Sin embargo, hay mucha información útil, y definitivamente otros podrán aplicarla a sus problemas. +1, y como solo queda una hora, también podría ser consciente de la recompensa. :)
Letharion
0

Una posible solución sería deshabilitar todo el token $form[‘#token’] = FALSE;, anular la devolución de llamada de envío en lugar de publicar el comentario, regenerar el formulario original con un token y pedirle al usuario que confirme la publicación.

Si el usuario admite ECMAScript , se podría mejorar la experiencia del usuario al tener un recurso de servicios que expone la generación de formularios de nuevos tokens de formulario e inserta el formulario relevante en el form_cache. Luego, tan pronto como el usuario se concentre en el formulario y, por lo tanto, es probable que desee enviarlo, desactive el botón de envío, busque un nuevo token e insértelo en el formulario ya renderizado, y habilite el botón de envío nuevamente.

Letharion
fuente