Outils pour utilisateurs

Outils du site


tips_informatiques:programmation:php:cakephp

Ceci est une ancienne révision du document !


Déboguer le SecurityComponent

CakePHP : 1.3.x

Le SecurityComponent est un composant bien utile de CakePHP permettant entre autre de sécuriser des formulaires: utilisé avec le FormHelper, il est responsable entre autre de:

  • ajouter un champ caché servant de ticket de validation lors du POST
  • comparer les champs affichés dans la page et les champs renvoyés en comparant un hash des noms des champs.

En cas d'erreur de ces comparaisons, par défaut le SecurityComponent affiche une page vide avec un code d'erreur HTTP.

Lors du développement, il peut alors être difficile de déterminer pour quelle raison un formulaire se bloque lors de l'envoi. Mais la plupart du temps la raison est que la comparaison des champs affichés par le FormHelper et les champs renvoyés (et donc vérifiés par le SecurityComponent) ne correspondent pas.

Comment comparer les champs affichés par le FormHelper et les champs renvoyés ?

SecurityComponent

Mettre un point d'arrêt de debug à la fin de la méthode _validatePost(&$controller) pour comparer les variables $token et $check

  ...
  $check = Security::hash(serialize($fieldList) . Configure::read('Security.salt'));
  return ($token === $check);
}

Si les valeurs de $token et $check sont différentes, on est bien dans le cas d'une différence entre champs affichés et champs renvoyés

Dans ce cas:

FormHelper

Mettre un point d'arrêt dans la méthode secure($fields = array()). Cette méthode est appelée par la méthode end($options = null) de FormHelper. Ce point d'arrêt permet de déterminer quels sont les champs affichés du formulaire (variable $fields en début de méthode) et le hash qui en découle (variable $fields en fin de méthode).

function secure($fields = array()) {
	if (!isset($this->params['_Token']) || empty($this->params['_Token'])) {
		return;
	}
 
	...
 
	$fields = Security::hash(serialize($fields) . Configure::read('Security.salt'));
 
	...
 
	return $out;
}

Réutiliser le point d'arrêt mis dans SecurityComponent afin de voir le contenu de $fieldList qui devrait être différent du contenu de $fields dans FormHelper.

A partir de là, il ne restera plus qu'à savoir d'où vient cette différence !

Note:

Une erreur courante empêchant le SecurityComponent de fonctionner est le fait de ne pas fermer les formulaires:

La fonction submit($caption = null, $options = array()) du FormHelper ne fait qu'imprimer un bouton submit, mais ne ferme pas le formulaire ! Ce qui signifie un code HTML invalide, et dans le cas présent le fait de ne pas passer par la méthode secure($fields = array()) nécessaire au fonctionnement du SecurityComponent.

Erreurs de validation non-montrées

CakePHP : 1.3.x

Alors que j'utilisais la méthode saveAll() dans un controller, les erreurs de validations des Models n'étaient pas montrées. J'ai cherché pendant un moment ce qu'il se passait dans la méthode elle-même, avant de comprendre que le problème se trouvait plus loin dans le code. Je faisais un nouveau read() depuis le Model principal, ce qui a pour effet de réinitialiser la variables $validationErrors !…

Le code suivant explique ceci:

Ici les erreurs ne sont pas montrées:

if (!empty($this->data)) 
{
  if ($this->User->saveAll($this->data, array('validate'=>'first'))) 
  {
    $this->Session->setFlash('User saved');
  } 
  else 
  {
    $this->Session->setFlash('User not saved.');
  }
}
 
$this->data = $this->User->read(null, $id);

Ici les erreurs sont montrées:

if (!empty($this->data)) 
{
  if ($this->User->saveAll($this->data, array('validate'=>'first'))) 
  {
    $this->Session->setFlash('User saved');
  } 
  else 
  {
    $this->Session->setFlash('User not saved.');
  }
} 
else 
{
    $this->data = $this->User->read(null, $id);
}
tips_informatiques/programmation/php/cakephp.1275992181.txt.gz · Dernière modification: 2010/06/08 00:00 (modification externe)