lithium\template\helper\Security::sign PHP Method

sign() public method

First FormSignature must be provided with a secret unique to your app. This is best done in the bootstrap process. The secret key should be a random lengthy string. php use lithium\security\validation\FormSignature; FormSignature::config(array('secret' => 'a long secret key')); In the view call the sign() method before creating the form. php security->sign(); ?> form->create(...); ?> Form fields... form->end(); ?> In the corresponding controller action verify the signature. php if ($this->request->is('post') && !FormSignature::check($this->request)) { The key didn't match, meaning the request has been tampered with. } Calling this method before a form is created adds two additional options to the $options parameter in all form inputs: - 'locked' _boolean_: If true, _locks_ the value specified in the field when the field is generated, such that tampering with the value will invalidate the signature. Defaults to true for hidden fields, and false for all other form inputs. - 'exclude' _boolean_: If true, this field and all subfields of the same name will be excluded from the signature calculation. This is useful in situations where fields may be added dynamically on the client side. Defaults to false.
See also: lithium\template\helper\Form
See also: lithium\security\validation\FormSignature
public sign ( object $form = null ) : void
$form object Optional. Allows specifying an instance of the `Form` helper manually.
return void
    public function sign($form = null)
    {
        $state =& $this->_state;
        $classes = $this->_classes;
        $form = $form ?: $this->_context->form;
        $id = spl_object_hash($form);
        $hasBound = isset($state[$id]);
        if ($hasBound) {
            return;
        }
        $form->applyFilter('create', function ($self, $params, $chain) use($form, &$state) {
            $id = spl_object_hash($form);
            $state[$id] = array('fields' => array(), 'locked' => array(), 'excluded' => array());
            return $chain->next($self, $params, $chain);
        });
        $form->applyFilter('end', function ($self, $params, $chain) use($form, &$state, $classes) {
            $id = spl_object_hash($form);
            if (!$state[$id]) {
                return $chain->next($self, $params, $chain);
            }
            $value = $classes['formSignature']::key($state[$id]);
            echo $form->hidden('security.signature', compact('value'));
            $state[$id] = array();
            return $chain->next($self, $params, $chain);
        });
        $form->applyFilter('_defaults', function ($self, $params, $chain) use($form, &$state) {
            $defaults = array('locked' => $params['method'] === 'hidden' && $params['name'] !== '_method', 'exclude' => $params['name'] === '_method');
            $options = $params['options'];
            $options += $defaults;
            $params['options'] = array_diff_key($options, $defaults);
            $result = $chain->next($self, $params, $chain);
            if ($params['method'] === 'label') {
                return $result;
            }
            $value = isset($params['options']['value']) ? $params['options']['value'] : "";
            $type = array($options['exclude'] => 'excluded', !$options['exclude'] => 'fields', $options['locked'] => 'locked');
            if (!($name = preg_replace('/(\\.\\d+)+$/', '', $params['name']))) {
                return $result;
            }
            $state[spl_object_hash($form)][$type[true]][$name] = $value;
            return $result;
        });
    }

Usage Example

Beispiel #1
0
 public function testFormSignatureWithLockedAndExcluded()
 {
     $form = new Form(array('context' => $this->context));
     $validator = 'lithium\\tests\\mocks\\security\\validation\\MockFormSignature';
     $helper = new Security(array('context' => $this->context, 'classes' => array('formSignature' => $validator)));
     $helper->sign($form);
     ob_start();
     $content = array($form->create(null, array('url' => 'http:///')), $form->text('email', array('value' => 'foo@bar')), $form->password('pass'), $form->hidden('id', array('value' => 23)), $form->text('foo', array('value' => 'bar', 'exclude' => true)), $form->hidden('active', array('value' => 'true', 'exclude' => true, 'locked' => false)), $form->end());
     ob_get_clean();
     $result = $validator::$compile[0]['in'];
     $expected = array('fields' => array('email', 'pass'), 'excluded' => array('foo', 'active'), 'locked' => array('id' => 23));
     $compiledSignature = $validator::$compile[0]['out'];
     $this->assertEqual($expected, $result);
     $request = new Request(array('data' => array('security' => array('signature' => $compiledSignature))));
     $validator::check($request);
     $expected = $compiledSignature;
     $result = $validator::$parse[0]['in']['signature'];
     $this->assertEqual($expected, $result);
     $result = $validator::$parse[0]['out'];
     $expected = array('excluded' => array('active', 'foo'), 'locked' => array('id' => 23));
     $this->assertEqual($expected, $result);
     $validator::reset();
 }