Dans cette publication, nous allons voir comment mettre en place un système d’identification basé sur le plugin sfDoctrineGuard. Pour que cela fonctionne, il vous faut également l’excellente librairie jquery. Dans cette article, je n’aborde pas l’installation du plugin, ni l’installation et le chargement de jquery.
Nous allons commencer par générer un nouveau module « user » dans notre projet avec la commande ci-dessous:
./symfony generate:module frontend user
Nous allons dès maintenant modifier notre module « user » pour y mettre notre propre code. Pour cela nous allons inclure la classe « BasesfGuardAuthActions » dans notre classe et changer l’extends:
require_once(sfConfig::get('sf_plugins_dir').'/sfDoctrineGuardPlugin/modules /sfGuardAuth/lib/BasesfGuardAuthActions.class.php'); class userActions extends BasesfGuardAuthActions { ... }
J’avais un problème a résoudre lors de l’affichage de la page signin lors de l’appel d’une page protégée. J’ai choisi d’y mettre uniquement une information utilisateur lui indiquant de s’identifier avec le formulaire. J’ai créé le fichier signinSuccess.php dans le dossier templates.
Nous allons maintenant monter le formulaire d’identification dans un component.
class userComponents extends sfComponents { public function executeSignin(sfWebRequest $request) { $class = sfConfig::get('app_sf_guard_plugin_signin_form', 'sfGuardFormSignin'); $this->form = new $class(); } }
template: _signin.php
<div id="form_message"> </div> <form id="guard" action="<?php echo url_for('@sf_guard_signin') ?>" method="post"> <?php echo $form->renderHiddenFields(); ?> <label>Utilisateur:</label> <?php echo $form['username']->render(); ?> <label>Mot de passe:</label> <?php echo $form['password']->render(); ?> <?php echo $form['remember']->render(array('id' => 'remember')); ?> Se souvenir de moi <input type="submit" value="S'identifier" /> <a href="<?php echo url_for('@sf_guard_password') ?>">Mot de passe oublié ?</a> </form> <script type="text/javascript"> $('#guard').submit(function() { $.post("<?php echo url_for('@sf_guard_signin'); ?>", $('#guard').serialize(), function(response) { switch(response.status) { case 'success': $('#form_message').html(response.message); $(location).attr('href',response.url); break; case 'failure': $('#form_message').html(response.message); $('#form_message').show(); break; } }, 'json'); return false; }); </script>
Nous allons rajouter un peu de css pour cacher notre zone « form_message »:
#form_message { display: none; font-weight: bold; color: red; }
Prochaine phase, désactiver les routes et y mettre nos propres paramètres. Nous allons pour cela toucher 3 fichiers:
app.yml
all: sf_guard_plugin: routes_register: false
routing.yml
sf_guard_signin: url: /login param: { module: user, action: signin } sf_guard_signout: url: /logout param: { module: user, action: signout } sf_guard_password: url: /password param: { module: user, action: password }
settings.yml
all: .actions: login_module: user login_action: signin secure_module: user secure_action: secure
La dernière phase de cette réalisation est l’implémentation de notre fonction signin. Voici le code utilisé pour un dialogue ajax:
class userActions extends BasesfGuardAuthActions { public function executeSignin($request) { $user = $this->getUser(); if ($user->isAuthenticated()) { return $this->redirect('@homepage'); } if($request->isMethod('post') && $request->isXmlHttpRequest()) { $class = sfConfig::get('app_sf_guard_plugin_signin_form', 'sfGuardFormSignin'); $form = new $class(); $form->bind($request->getParameter($form->getName())); if ($form->isValid()) { $values = $form->getValues(); $user->signin($values['user'], array_key_exists('remember', $values) ? $values['remember'] : false); $signinUrl = sfConfig::get('app_sf_guard_plugin_success_signin_url', $user->getReferer($request->getReferer())); return $this->renderText(json_encode(array('status' => 'success', 'url' => $signinUrl))); } else { return $this->renderText(json_encode(array('status' => 'failure','message' => 'Identification incorrecte'))); } } $this->getResponse()->setStatusCode(401); } }
Il nous reste plus qu’à insérer notre component dans notre layout ou notre template:
<?php if (!$sf_user->isAuthenticated()): ?> <?php include_component('user', 'signin'); ?> <?php endif; ?>
L’implémentation est terminée. J’espère que ce petit article vous permettra de mettre en place un formulaire à la web 2.0 😉
Bonjour, j’ai suivis votre tuto à la lettre et malheureusement, je n’arrive pas a faire marcher malgré mes différentes recherches.
Quand j’essaye de m’identifier avec un mauvais pass, je tombe sur le template signingSuccess du module « user » avec pour adresse http://www.monsite.com/login et quand j’essaye le bon pass même chose, rien ne s’affiche dans le div message, je ne vois vraiment pas où je me suis planté.
Merci par avance de votre aide.
Bonjour,
J’ai essayé ce code. Il fonctionne très bien lorsque l’authentification échoue. En revanche, j’ai une erreur 500 lorsque l’identification est bonne.
Je pense que c’est une bêtise mais je n’arrive pas à trouver.
merci par avance
Bonjour,
Après avoir réalisé les opérations décrites si dessus, j’obtiens une erreur ;
The component does not exist: « sfGuardAuth », « signin ».
Il me semble que ce sont les fichiers du plugins qui sont appelés alors que dans le cas présent on re-déclare ces fichiers dans le module de l’application
Une idée du fichier à modifier ?
Pour éviter de revenir à la page d’accueil à chaque fois qu’on se connecte sur une page, dans certains cas, il est plus confortable de juste réafficher la page où l’utilisateur est présent. Pour cela, j’ai modifié la classe userActions
06 if ($user->isAuthenticated())
07 {
08 return $this->redirect(‘@homepage’);
09 }
PAR
if ($user->isAuthenticated()) {
return $this->redirect($_SERVER[‘HTTP_REFERER’]);
}
Maintentant ton exemple est au poil 😉
est ce que vous pouvez me dire ce que le template signinSuccess.php contient comme code?
Bonjour,
Comme j’utilise un component pour afficher mon formulaire, le contenu du form est dans le fichier _signin.php. Vous le trouvez dans le tutorial.
Excellent article ! J’essaie ça à ma prochaine application symfony. 😉
Bonjour,
Merci pour cette petite astuce qui sera forte utile !
J’ai juste une petite question concernant la validation des erreurs : si la personne ne saisit pas de mot de passe, qu’y a-t-il comme erreur d’indiquée ? Identification incorrecte non ?
Je trouve cela assez dommage de perdre le bénéfice des validateurs symfony pour placer un peu d’ajax qui au final, retire un peu d’interactivité alors qu’il est censé en ajouter :p
Mais c’est mon point de vue 🙂
Vous avez toujours la possibilité de gérer les erreurs dans le retour json. Il suffit pour cela de personnaliser le cellule du tableau « message ».
Dans mon cas, je préfère ne pas donner trop de renseignements sur le type d’erreur.
Bonjour Bertrand et merci pour l’article
Je suis encore un novice en symfony et j’ai juste remarqué (d’après mes tests au moins!), que le code du toto ne permet pas de rediriger vers une page 401 en cas d’accès non autorisé à une ressource protégée
n’avez vous pas pris en compte cette fonctionnalité ou c moi qui a un problème quelques parts ?
Bonjour,
Si une ressource est protégée et que l’utilisateur n’est pas identifié, il sera redirigé vers l’action de login. Ce sont les options définies dans le fichier settings.yml. Par contre, s’il est identifié mais qu’il n’a pas les autorisations nécessaires, il sera aiguillé sur l’action secure également définie dans le fichier settings.yml. J’espère que cette explication est claire. A vous de réaliser cette action qui n’est pas décrite dans ce tuto.