Login et authentification avec le Zend Framework
J’ai reçu un certain nombre de questions de personnes voulant savoir comment utiliser l’authentification et la persistance d’identité dans le Zend Framework. La question récurrente est de savoir comment combiner :
- un adapteur d’authentification
- un formulaire de login
- un controlleur pour les actions de login/logout
- la vérification de l’authentification d’un utilisateur déjà authentifié lors de ses requêtes suivantes
Ce n’est pas insurmontable, mais cela demande de savoir comment les différents éléments du modèle MVC travaillent ensemble, et comment utiliser le composant Zend_Auth. Jetons un coup d’oeil.
Adaptateur d’authentification
Pour cette partie, vous aurez besoin d’un adaptateur d’authentification. Je ne rentrerai pas dans les détails d’utilisation de ce composant, car la documentation couvre parfaitement son fonctionnement et vos besoins peuvent varier en fonction de votre site. Je supposerai toutefois, que votre adaptateur d’authentification demande un login et un mode de passe comme identifiants. Notre contrôleur d’identification se servira de l’adaptateur, mais aura simplement un emplacement réservé pour le retrouver.
Formulaire d’authentification
Le formulaire d’authentification a proprement parler est vraiment simple. Vous pouvez ajouter quelques règles basiques de validation afin de prévenir toute attaque de la base de données ou d’un autre élément, mais penser à garder l’ensemble relativement simple. Pour les besoins de ce tutoriel, nous allons définir les critères suivants :
- le nom d’utilisateur doit se composer uniquement de caractère alphabétique, et doit contenir entre 3 et 20 caractères
- le mot de passe sera constitué uniquement de caractères alphanumériques, et doit contenir entre 6 et 20 caractères
Le code du formulaire ressemblera à ceci :
{
public function init()
{
$username = $this->addElement(‘text’, ‘username’, array(
‘filters’ => array(‘StringTrim’, ‘StringToLower’),
‘validators’ => array(
‘Alpha’,
array(‘StringLength’, false, array(3, 20)),
),
‘required’ => true,
‘label’ => ‘Your username:’,
));
$password = $this->addElement(‘password’, ‘password’, array(
‘filters’ => array(‘StringTrim’),
‘validators’ => array(
‘Alnum’,
array(‘StringLength’, false, array(6, 20)),
),
‘required’ => true,
‘label’ => ‘Password:’,
));
$login = $this->addElement(’submit’, ‘login’, array(
‘required’ => false,
‘ignore’ => true,
‘label’ => ‘Login’,
));
// Nous souhaitons afficher un message’failed authentication’ si nécessaire;
// nous le ferons avec le champs ‘description’, nous avons donc besoin
// d’ajouter decorator.
$this->setDecorators(array(
‘FormElements’,
array(‘HtmlTag’, array(‘tag’ => ‘dl’, ‘class’ => ‘zend_form’)),
array(‘Description’, array(‘placement’ => ‘prepend’)),
‘Form’
));
}
}
Login Controller
Maintenant, nous allons créer un contrôleur pour gérer les actions de login et de logout. Le cas d’utilisation typique serait :
- l’utilisateur clique sur le lien du formulaire d’authentification
- l’utilisateur soumet le formulaire
- le contrôleur traite le formulaire
- une erreur de validation provoque l’affichage du formulaire avec le ou les messages d’erreurs
- une identification correcte redirige vers la page d’accueil
- l’utilisateur connecté est redirigé vers la page d’accueil
- l’action logout déconnecte l’utilisateur et le redirige vers le formulaire de login
Le LoginController se servira aussi bien de l’adaptateur d’authentification que vous avez choisi, que du formulaire d’authentification. Nous passerons au constructeur du formulaire de login l’action et la méthode de formulaire (puisque nous savons maintenant ce qu’ils font pour cette usage du formulaire).
Lorsque nous aurons des valeurs valides, nous les passerons à notre adaptateur d’authentification.
Allons y, créons le contrôleur. En premier, nous allons créer les accesseurs pour le formulaire et l’adaptateur d’authentification.
{
public function getForm()
{
return new LoginForm(array(
‘action’ => ‘/login/process’,
‘method’ => ‘post’,
));
}
public function getAuthAdapter(array $params)
{
// Laissé au soin du développeur…
// Suppose que le constructeur prend un tableau de
// paramètres qu’il utilise comme identifiant afin de vérifier l’identité.
// Bien sur, notre formulaire passera seulement les paramètres ‘nom d’utilisateur’
// et ‘mot de passe’.
}
}
Ensuite, nous avons besoin d’effectuer quelques vérifications, avant de dispatcher une quelconque action, afin de s’assurer :
- que si un utilisateur est déjà authentifié, mais n’a pas effectué d’action de déconnexion, il sera redirigé vers la page d’accueil
- que si l’utilisateur n’est pas authentifié, mais a soumis une requête pour se déconnecter, nous devons le redirigé vers la page de login
La routine preDispatch() ci-dessous effectuera cela pour nous:
{
// …
public function preDispatch()
{
if (Zend_Auth::getInstance()->hasIdentity()) {
// Si l’utilisateur est identifié, nous ne souhaitons pas voir le formulaire d’authentification;
// cependant, l’action de déconnexion devrait toujours rester disponible.
if (‘logout’ != $this->getRequest()->getActionName()) {
$this->_helper->redirector(‘index’, ‘index’);
}
} else {
// If they aren’t, they can’t logout, so that action should
// redirect to the login form
if (‘logout’ == $this->getRequest()->getActionName()) {
$this->_helper->redirector(‘index’);
}
}
}
}
Maintenant, nous devons réaliser notre formulaire de login. Ce sera notre méthode la plus simple — il suffit de récupérer le formulaire et de l’assigner à la vue:
{
// …
public function indexAction()
{
$this->view->form = $this->getForm();
}
}
Le traitement du formulaire implique légèrement plus de logique. Nous devons vérifier qu’il provient bien d’une requête POST, que son contenu est valide et enfin que les paramètres d’authentification soient corrects.
{
// …
public function processAction()
{
$request = $this->getRequest();
// Vérifier que nous avons bien à faire à une requête POST
if (!$request->isPost()) {
return $this->_helper->redirector(‘index’);
}
// Récupérons le formulaire et validons le
$form = $this->getForm();
if (!$form->isValid($request->getPost())) {
// Entrées invalides
$this->view->form = $form;
return $this->render(‘index’); // rechargeons le formulaire
}
// Récupérons notre adaptateur d’authentification et vérifions les identifiants
$adapter = $this->getAuthAdapter($form->getValues());
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
if (!$result->isValid()) {
// Identifiants invalides
$form->setDescription(‘Invalid credentials provided’);
$this->view->form = $form;
return $this->render(‘index’); // rechargeons le formulaire
}
// Nous sommes authentifiés, redirection vers la page d’accueil
$this->_helper->redirector(‘index’, ‘index’);
}
}
Finalement, nous pouvons aborder l’action de logout. C’est presque aussi simple que l’affichage du formulaire d’authentification; nous devons simplement effacer l’identité de l’utilisateur de l’objet d’authentification et rediriger:
{
// …
public function logoutAction()
{
Zend_Auth::getInstance()->clearIdentity();
$this->_helper->redirector(‘index’); // Retournez à la page de login
}
}
Ok, nous venons de mettre en place les routines de login/logout. Jetons un œil à la seule vue associée que nous ayons, le formulaire:
<h2>Please Login</h2>
<?= $this->form ?>
Voilà c’est tout. Le composant Zend_Form permet vraiment d’avoir des scripts de vues simples. ![]()
Vérifications pour utilisateurs authentifiés
La dernière chose à voir est : comment puis je déterminer qu’un utilisateur est authentifié, et restreindre son accès s’il ne l’est pas ?
Si vous regarder attentivement la méthode preDispatch() vue plus haut, vous remarquerez que cela est peut être déjà fait. Zend_Auth rend persistante l’identité dans la session, ce qui vous permet de la vérifier directement en utilisant la construction suivante:
Vous pouvez vous en servir pour déterminer si l’utilisateur est authentifié, et dans le cas contraire rediriger l’utilisateur vers la page de login avec l’aide du redirector. Vous pouvez récupérer l’identité depuis l’objet auth de la manière suivante:
Cela pourrait être utilisé dans un helper afin de montrer le statut de connexion dans le template, par exemple:
* ProfileLink helper
*
* Call as $this->profileLink() in your layout script
*/
class My_View_Helper_ProfileLink
{
public $view;
public function setView(Zend_View_Interface $view)
{
$this->view = $view;
}
public function profileLink()
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$username = $auth->getIdentity()->username;
return ‘<a href=”/profile’ . $username . ‘”>Welcome, ‘ . $username . ‘</a>’;
}
return ‘<a href=”/login”>Login</a>’;
}
}
Conclusion
Zend_Auth réalise la plupart du travail en arrière plan pour faire de la persistance d’identité dans la session une banalité. Combinez-le avec Zend_Form, et vous aurez une solution très facile à mettre en œuvre pour retrouver et valider des identifiants; ajoutez à cela les évènements dans le composant Zend_Controller pour filtrer les actions avant de les rediriger, et vous pouvez restreindre très facilement l’accès aux applications en utilisant le statut d’authentification.
Nota : Cette traduction est livrée telle quelle, si toutefois vous constatez une erreur de traduction, je suis bien sur ouvert à toute correction.
Tags: authentication, authentification, framework, login, logout, matthew, matthiew weier o'phinney, mvc, objet, php, poo, Tutoriel, weier o'phinney, zend, Zend Framework, Zend_Auth, Zend_Form


juillet 21st, 2008 at 14:35
Merci pour cet article constructif concernant l’autentification sous Zend
A mettre en pratique
octobre 13th, 2008 at 15:03
Bonjour,
J’ai une question au sujet de cet article. Apparemment il n’est applicable qu’aux sites utilisant la partie MVC du ZF. Y a-t’il des exemples d’utilisation du module Zend_Auth si on n’utilise pas le MVC de ZF ?
novembre 6th, 2008 at 11:56
Hi,can I get this article in english?
Thanks
novembre 6th, 2008 at 16:19
@xsirro : As I wrote in the beginning of my article, you could find the original on Matthew website at this url : http://weierophinney.net/matthew/archives/165-Login-and-Authentication-with-Zend-Framework.html.
Bests Regards,