ajax - google - tag manager form submission trigger
Cómo usar el Hash Framework Form Hash(token) con AJAX (6)
Así es como se maneja el campo hash en forma ajax:
class AuthController extends Zend_Controller_Action
{
public function init()
{
$contextSwitch = $this->_helper->getHelper(''contextSwitch'');
$contextSwitch->addActionContext(''index'', ''json'')
->initContext();
}
public function loginAction()
{
$form = new Application_Form_Login();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
// some code ..
} else {
// some code ..
// Regenerate the hash and assign to the view
$reservationForm->hash->initCsrfToken();
$this->view->hash = $reservationForm->hash->getValue();
}
}
$this->view->form = $form;
}
}
Y luego en tu script de vista ...
<? $this->dojo()->enable()
->requireModule(''dojox.json.query'')
->onLoadCaptureStart() ?>
function() {
var form = dojo.byId("login_form")
dojo.connect(form, "onsubmit", function(event) {
dojo.stopEvent(event);
var xhrArgs = {
form: this,
handleAs: "json",
load: function(data) {
// assign the new hash to the field
dojo.byId("hash").value = dojox.json.query("$.hash", data);
// some code ..
},
error: function(error) {
// some code ..
}
}
var deferred = dojo.xhrPost(xhrArgs);
});
}
<? $this->dojo()->onLoadCaptureEnd() ?>
Espero que no sea demasiado tarde: D
He incluido Zend_Form_Element_Hash en un formulario de casilla de verificación de múltiples formas. Tengo jQuery configurado para desencadenar una solicitud AJAX cuando se hace clic en una casilla de verificación, paso el token con esta solicitud AJAX. La primera solicitud de AJAX funciona muy bien, pero las posteriores fallan.
Sospecho que puede ser que una vez que se haya validado el token se elimine de la sesión (salto = 1).
¿Cuál sería su plan de ataque para asegurar un formulario con Zend Framework Hash y usar AJAX para completar algunas de estas solicitudes?
Finalmente abandoné el uso de Zend_Form_Element_Hash y simplemente creé un token manualmente, lo registré con Zend_Session y luego lo verifiqué al enviarlo.
form.php
$myNamespace = new Zend_Session_Namespace(''authtoken'');
$myNamespace->setExpirationSeconds(900);
$myNamespace->authtoken = $hash = md5(uniqid(rand(),1));
$auth = new Zend_Form_Element_Hidden(''authtoken'');
$auth->setValue($hash)
->setRequired(''true'')
->removeDecorator(''HtmlTag'')
->removeDecorator(''Label'');
controller.php
$mysession = new Zend_Session_Namespace(''authtoken'');
$hash = $mysession->authtoken;
if($hash == $data[''authtoken'']){
print "success";
} else {
print "you fail";
}
Esto parece funcionar y aún mantiene las cosas relativamente sanas y seguras. Todavía prefiero usar el elemento Hash, pero parece que no puedo hacer que funcione con AJAX.
Gracias a todos.
Hay una solucion:
Cree, además del formulario que contendrá los datos, un formulario sin elementos. Desde el controlador se instancian las dos formas. También en el controlador, agrega el elemento hash al formulario vacío. Ambas formas deben ser enviadas a la visión. Luego, en la condición "if ($ request-> isXmlHttpRequest ())" en el controlador, renderice el formulario vacío. Luego, toma el valor hash con el método "getValue ()". Este valor debe enviarse en respuesta por Ajax y luego usar JavaScript para reemplazar el valor de hash que ya está obsoleto. La opción de crear un formulario vacío para el hash es evitar problemas con otros elementos, como el captcha, que volvería a generar su id si se procesara el formulario, y también necesitaría reemplazar la nueva información. La validación se hará por separado porque hay dos formas distintas. Más tarde puede reutilizar el formulario de hash (vacío) cuando lo desee. Los siguientes son ejemplos del código.
//In the controller, after instantiating the empty form you add the Hash element to it:
$hash = new Zend_Form_Element_Hash(''no_csrf_foo'');
$hash_form->addElement(''hash'', ''no_csrf_foo'', array(''salt'' => ''unique''));
//...
//Also in the controller, within the condition "if ($request->isXmlHttpRequest())" you render the form (this will renew the session for the next attempt to send the form) and get the new id value:
$hash_form->render($this->view);
$hash_value[''hash''] = $hash_form->getElement(''no_csrf_foo'')->getValue();//The value must be added to the ajax response in JSON, for example. One can use the methods Zend_Json::decode($response) and Zend_Json::encode($array) for conversions between PHP array and JSON.
//---------------------------------------
//In JavaScript, the Ajax response function:
document.getElementById("no_csrf_foo").value = data.hash;//Retrieves the hash value from the Json response and set it to the hash input.
León
Las formas de hashes son grandes en principio y un poco de pesadilla en la práctica. Creo que la mejor manera de manejar esto es devolver el nuevo hash con la respuesta cuando realice una solicitud, y actualizar el marcado del formulario o almacenar en la memoria para su javascript según corresponda.
El nuevo hash puede estar disponible desde el objeto de formulario, o puede leerlo desde la sesión.
Si desea utilizar el validador de formularios en el lado ajax, utilice el siguiente código:
Myform.php
class Application_Form_Myform extends Zend_Form
{
# init function & ...
public function generateform($nohash = false)
{
# Some elements
if(!$nohash)
{
$temp_csrf = new Zend_Session_Namespace(''temp_csrf'');
$my_hash = new Zend_Form_Element_Hash ( ''my_hash'' );
$this->addElement ( $my_hash , ''my_hash'');
$temp_csrf->hash = $my_hash->getHash();
}
# Some other elements
}
}
AjaxController.php
class AjaxController extends Zend_Controller_Action
{
// init ...
public function validateAction()
{
# ...
$temp_csrf = new Zend_Session_Namespace(''temp_csrf'');
if($temp_csrf->hash == $params[''received_hash_from_client''])
{
$Myform = new Application_Form_Myform();
$Myform->generateform(true);
if($AF_Bill->isValid($params))
{
# Form data is valid
}else{
# Form invalid
}
}else{
# Received hash from client is not valid
}
# ...
}
}
Usted insinuó la respuesta correcta en su pregunta: aumente el número de saltos.
Hubo una mención específica de esto en el manual de ZF en línea, pero actualizaron sus manuales y ahora no puedo encontrarlo (sonrisa). De lo contrario, habría publicado el enlace para usted.