How to use Zend Framework Form Hash (token) with AJAX How to use Zend Framework Form Hash (token) with AJAX ajax ajax

How to use Zend Framework Form Hash (token) with AJAX


I finally abandoned using Zend_Form_Element_Hash and just created a token manually, registered it with Zend_Session and then checked it upon submission.

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";}

This seems to work and still keeps things relatively sane and secure. I'd still rather use the Hash element, but I can't seem to make it work with AJAX.

Thanks all.


That's how to handled hash field in ajax form :

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;    }}

And then in your view script ..

<? $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() ?>

Hope it's not too late :D


There is a solution:

Create, besides the form that will contain the data, a form without elements. From the controller you instantiate the two forms. Also in the controller, you add the element hash to the empty form. Both forms should be sent to the vision. Then, in the condition "if ($ request-> isXmlHttpRequest ())" in the controller you render the empty form. Then, you take the hash value with the method "getValue ()". This value must be sent in response by Ajax and then use JavaScript to replace the hash value that is already obsolete. The option to create an empty form for the hash is to avoid problems with other elements such as captcha that would have its id generated again if the form were rendered, and would also need to have the new information replaced. The validation will be done separately because there are two distinct forms. Later you can reuse the hash (empty) form whenever you want. The following are examples of the code.

//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