Zend Framework : Authentification avec Zend_Auth_Adapter_DbTable

Posté par seiyar81 le 27 janvier 2010 | Laisser un commentaire (17)

Aujourd’hui je vais expliquer comment réaliser simplement avec le Zend Framework une authentification avec la classe Zend_Auth_Adapter_DbTable.

Cette classe va grandement nous simplifier la vie puisqu’elle va comparer pour nous le couple username/password dans une table dont on lui fournira les champs.
Autrement dit, plus besoin de s’embêter à sélectionner et comparer les valeurs à la main.

Pour commencer nous allons créer notre model pour la table qui stocke nos utilisateurs. Imaginons qu’elle s’appelle ‘users‘ et qu’elle possède au moins deux champs : ‘username’ et ‘password’.

<?php 

class Default_Model_DbTable_Users extends Zend_Db_Table
{
    protected $_name = 'users';

}

La classe est ici déclarée sans autres méthodes pour l’exemple mis vous pouvez très bien en ajouter. De plus j’ai nommé ma classe de telle sorte qu’elle est déclarée dans le fichier : ‘application/models/DbTable/Users.php‘. Libre à vous de faire autrement.

Ensuite vous pouvez créer un formulaire en héritant la classe Zend_Form :

<?php

class Default_Form_Login extends Zend_Form
{
    public function __construct($options = null)
    {
        parent::__construct($options);
        $this->setName('login_form');
        $this->setAction('/auth/login')
     	->setMethod('post');

        $username = new Zend_Form_Element_Text('username');
        $username ->setLabel('Username : ')
        ->setRequired(true)
        ->addFilter('StripTags')
        ->addFilter('StringTrim')
        ->addValidator('NotEmpty');

        $password = new Zend_Form_Element_Password('password');
        $password->setLabel('Mot de passe : ')
        ->setRequired(true)
        ->addFilter('StripTags')
        ->addFilter('StringTrim')
        ->addValidator('NotEmpty');

        $submit = new Zend_Form_Element_Submit('Login');
        $submit->setAttrib('id', 'submitbutton');
        $submit->setValue('Login');

        $this->addElements(array($username, $password, $submit));
    }
}

De même, j’ai ici fait au plus simple. La classe est déclarée dans le fichier ‘application/forms/Login.php‘.
Il ne vous reste plus qu’a déclarer le formulaire dans le contrôleur gérant l’authentification. Par exemple :

<?php

class AuthController extends Zend_Controller_Action
{

    public function init()
    {
        $this->initView();
	$this->view->baseUrl = $this->_request->getBaseUrl();
    }

    public function loginAction()
    {
    	$this->view->title="Mon Site Web - Login";
        $form =  new Default_Form_Login();
        $this->view->form = $form;
    }

}

On affiche le formulaire dans notre fichier vue :

<?php 
    echo $this->form;
    echo '<br />';
    echo $this->error;
?>

Voilà tout est en place pour nous permettre maintenant d’utiliser Zend_Auth_Adapter_DbTable.
On va donc ajouter dans l’action login de notre contrôleur :

    public function loginAction() 
    {
        // Si l'utilisateur est déjà loggué on le redirige à l'accueil
    	if(Zend_Auth::getInstance()->hasIdentity()) $this->_redirect('/index');

    	$this->view->title="Mon Site Web - Login";

		$form = new Default_Form_Login();
		$this->view->form = $form;	
                $formData = $this->getRequest()->getPost();

		if($this->getRequest()->isPost()) {
	            if ($form->isValid($formData)) {
					$username = $form->getValue('username');
					$password = $form->getValue('password');

					$dbAdapter = Zend_Db_Table_Abstract::getDefaultAdapter();
					$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
					$authAdapter->setTableName('users');
					$authAdapter->setIdentityColumn('username');
					$authAdapter->setCredentialColumn('password');

					// On assigne les valeurs pour que l'authentification s'effectue
					$authAdapter->setIdentity($username);
					$authAdapter->setCredential(sha1($password)); // On a pris la précaution d'au moins chiffrer les mdp

					// On tente l'authentification
					$auth = Zend_Auth::getInstance();
					$result = $auth->authenticate($authAdapter);
                         // On test si tout s'est bien passé
	                if($result->isValid()) 	
	                	{
	                		$data = $authAdapter->getResultRowObject(null, 'password');
					$auth->getStorage()->write($data);
					$this->_redirect('/admin');
	                	}
	                	else
	                	{
	                	$this->view->error = 'Mauvais login ou mauvais mot de passe.';
                    		$form->populate($formData);
	                	}
				    }
		    	else {
	                $this->view->error = 'Vous devez remplir tous les champs.';
                        $form->populate($formData);
		    	}
		}
    }

Et voilà ZF a automatiquement géré l’authentification pour nous. On peut maintenant accéder au données de l’utilisateur via Zend_Auth::getInstance()->getIdentity().
Ainsi si on veut afficher le nom de l’utilisateur :

<?php
     $auth = Zend_Auth::getInstance()->getIdentity();
     echo $auth->username;
?>

Et voilà, bientôt de nouveaux articles sur l’utilisation du Zend Framework.

Catégorie: Développement Web, PHP, Zend Framework | Laisser un commentaire (17)


17 commentaires pour “Zend Framework : Authentification avec Zend_Auth_Adapter_DbTable”

  • Salut,

    D’abord merci pour ton explication sur le composant Auth, je suis néophyte avec ZF et j’avoue que ton tuto m’aide bien.

    J’ai par contre un petit problème dans mon contrôleur, j’ai une erreur à cause de $form->populate($formData); ==> Undefined variable: formData.

    Quelqu’un sait d’où pourrait provenir le problème ?

    Merci

  • En effet il manquait une ligne dans le code.

    $formData doit contenir les variables envoyées au serveur afin de remplir le formulaire.

    Comme tu peux le voir dans la mise à jour du code, il faut initialiser cette variable avec la superglobale $_POST.

    Rien ne t’empêche cependant de directement faire : $form->populate($_POST);

  • J’ai trouvé une solution qui marche, j’ai ajouté :

    $formData = $this->getRequest()->getPost();

    au début de la fonction loginAction().

  • En effet cela revient au même, si ce n’est que c’est plus long à écrire^^

  • Bonjour,

    Merci beaucoup pour ce tutoriel 🙂
    Mais j’ai un petit soucis lorsque je l’exécute cela m’affiche
    ” An error occurred
    Application error ”
    Seriez vous de quoi il s’agit ?

    Cordialement

  • Malheureusement beaucoup de choses peuvent causer cette erreur.
    Elle est plus sûrement liée à la configuration de l’environnement ou quelque chose comme ça.
    Il faudrait plus d’infos pour déterminer la réelle source de l’erreur.
    Pour cela il suffit de passer l’environnement en “mode test”.

  • Merci pour de m’avoir répondu,
    Je débute en zend, et je ne connais pas le ” mode test ” de quoi s’agit il ?
    Merci d’avance

  • Lorsqu’on créé une application avec Zend il faut lui définir un environnement, qu’il soit de test, développement ou production.
    Les environnements sont définis en général dans le fichier (selon l’architecture par défaut des projets) application/configs/application.ini.
    Logiquement on développe le projet en mode development, on le test en mode test et on le passe en mode production lorsqu’il est terminé.
    Les modes test et development activent l’affichage des erreurs de l’application.

    Essayez de le passez en mode development.
    Pour cela dans le fichier public/index.php mettez ceci en dessous de

    // Define application environment
    defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));

  • Merci pour cette explication !!!
    Je vais essayer de me débugger maintenant que je peux voir les messages d’erreurs 😀 !!

  • Bonjour et merci pour ce tuto,

    j’ai un problème :
    quand je rentre un identifiant et que je valide, il ne se passe rien. Que le couple username/password concorde ou pas.
    (je n’arrive pas à afficher Mauvais login ou mauvais mot de passe.)
    Et quand je ne rentre pas un champ, j’ai un message d’avertissement en anglais et pas le message en français : Vous devez remplir tous les champs.

    Savez-vous d’où vient le problème ? Merci d’avance

  • Bonjour,

    Je ne l’ai pas précisé dans le tuto, c’est de ma faute, mais on stocke l’erreur (mauvais login/mot de passe ou champs manquant) dans la variable $this->view->error.
    Pour l’afficher il faut ajouter dans la vue à l’endroit souhaité :
    echo $this->error;
    Cela devrait mieux fonctionner maintenant 😉

  • Bonjour

    Merci beaucoup pour les explications .

  • Bonjour
    Merci pour cette explication , elle m’a beaucoup servi ;
    j’ai un problème c’est que je ne sais pas différentier entre “username” et “login” .
    Ma table contient 3 champs un ID,un login et un mot de passe; je demande est ce que “login” ici ressemble à le mien, ou c’est le nom de l’action qu’on a créer ci dessus ?
    J’ai besoin de votre aide;
    merci d’avance.

  • Ce n’est pas expliqué assez clairement dans le début du tuto mais on part du principe que la table users a au moins 2 champs : ‘username’ et ‘password’.
    J’ai modifié le code afin que le champ du formulaire et le champ de la base aient le même nom.
    Du coup login correspond seulement au nom de l’action dans l’exemple.

  • Bonjour!
    Merci beaucoup pour ce tutoriel
    ça marche bien 🙂 .
    Mais svp j’ai besoin d’une explication étendu de chaque fonction/action . cela m’aidera de bien faire mon rapport .
    Merci d’avance.

  • Bonjour, j’aime bien votre tutoriel sur l’authentification sous zend framework mais ce qui m’étonne c’est que j’ai pu la faire sans passer par les forms ni les models, comment?
    De plus je vous supplie de me fournir une explication détaillée de la dernière partie ( celle de loginAction), j’en profiterais pour ma soutenance.
    Merciii c’est sympathique!

  • Bonjour,
    La fonction loginAction est très simple, on commence par instancier notre formulaire et on l’assigne à la vue.
    Lorsqu’on appelle simplement la page login, on effectue une requête GET et on ne rentre pas dans la condition $this->getRequest()->isPost().
    Une fois la formulaire envoyé, on récupère les données envoyées en POST et on les traite.
    On commence par valider le formulaire avec if ($form->isValid($formData)) et ensuite on traite l’authentification.
    Si $auth->authenticate($authAdapter) est valide alors on récupère notre User en mettant à null la colonne password :
    $data = $authAdapter->getResultRowObject(null, ‘password’);
    $auth->getStorage()->write($data);

Laissez un commentaire