Pregunta

He incluido Zend_Form_Element_Hash en una forma multiplecheckbox forma. Tengo jQuery ajustado a disparar una petición AJAX cuando se hace clic en una casilla de verificación, paso el testigo con esta petición AJAX. La primera petición AJAX funciona muy bien, pero los posteriores falle.

Sospecho que puede ser una vez que el contador se ha validado que se retira entonces de la sesión (salto = 1).

¿Cuál sería su plan de ataque para asegurar un formulario con Zend Framework Hash sin embargo el uso de AJAX para completar algunas de estas peticiones?

¿Fue útil?

Solución

Finalmente abandoné usando Zend_Form_Element_Hash y acabo de crear una ficha de forma manual, registrada con Zend_Session y después se comprueba que tras la presentación.

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 todavía mantiene las cosas relativamente sano y seguro. Todavía prefiero usar el elemento hash, pero me parece que no puede hacer que funcione con AJAX.

Gracias a todos.

Otros consejos

Así es como campo de hash para manejarse 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 a continuación, en su 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

Hay una solución:

Crea, además de la forma que contendrá los datos, una forma sin elementos. Desde el controlador se ejemplariza las dos formas. También en el controlador, se agrega el hash elemento a la forma vacía. Ambas formas deben ser enviadas a la visión. A continuación, en la condición "if ($ request-> isXmlHttpRequest ())" en el controlador procese la forma vacía. A continuación, se toma el valor hash con el método "getValue ()". Este valor debe ser enviada en respuesta por el Ajax y luego usar JavaScript para sustituir el valor hash que es ya obsoleto. La opción de crear una forma vacía para el hash es para evitar problemas con otros elementos como el código de imagen que tendría su ID generado de nuevo si el formulario se rindió, y también tendría que tener la nueva información reemplazado. La validación se realiza de forma separada, porque hay dos formas distintas. Más tarde se puede volver a utilizar la forma de almohadilla (vacío) siempre que 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.

Leo

hashes de la forma son en principio y un poco de una pesadilla en la práctica. Creo que la mejor manera de manejar esto es devolver el nuevo hash con la respuesta cuando se hace una petición, y actualizar el marcado de forma o almacenarlos en la memoria para su Javascript en su caso.

La nueva almohadilla puede estar disponible en el objeto de formulario, o puede leerlo de la sesión.

insinuado la respuesta correcta en su pregunta: aumentar el número de saltos

.

No hubo mención específica de esto en el manual ZF en línea, sino que actualiza sus manuales y ahora no lo encuentra (sonrisa) -. De lo contrario habría publicado el enlace para usted

Si desea utilizar el formulario de validación en uso lado ajax siguiente código:

miformulario.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
         }
         # ... 
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top