Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 09-12-2011 10:02:22

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

[Zend 1.11][Zend_Auth et autre]Problème actualisation profil

Bonjour, je tiens à m'excuser si le sujet a déjà été traité, cependant je n'ai pas trouvé de sujet traitant de mon problème.

Pour faire simple, j'ai un site web en PHP ainsi qu'un forum Fluxbb qui tournent actuellement. Tout fonctionne très bien, j'utilise le système d'authentification et de chargement du profil du forum, à savoir une requête SQL qui va récupérer à chaque action les informations de l'utilisateur en base de données en fonction de l'identifiant présent dans le cookie et de la session. Je précise que tout ceci est crypté afin de ne pas permettre une modification de l'identifiant via des logiciels d'édition de cookie. Avec ce système lorsque je banni un utilisateur, la prochaine requête qu'il va exécuté récupèrera ces informations là et l'utilisateur sera donc bloqué. Je parle de bannissement mais ça fonctionne de la même manière pour tout information du profil (changement de droits etc ...)

Je souhaite me former au Zend Framework, pour ça j'ai lu plusieurs tutoriels, regardé des vidéos explicatives et parcouru ce forum. J'arrive donc naturellement à l'étape d'évolution de mon site web vers ce framework.

Cette évolution se passe plutôt bien et j'en arrive à la partie identification sur mon application. Pour se faire j'utilise le composant Zend_Auth dans un contrôleur Login.

Voici à quoi ressemble mon code d'authentification :

Code:

[lang=php]public function loginAction() {

        // Récupération de la requête
        $request = $this->getRequest();

        // Vérification si la page a bien été appelée à partir d'un formulaire
        if ($request->isPost()) {
            $loginForm = new Application_Form_Login();
            // Enregistrement des données envoyées à partir du formulaire dans un tableau
            $data = $request->getPost();

            // Validation du formulaire
            if ($loginForm->isValid($data)) {
                $login = $data['login'];
                $password = $data['password'];

                //création d'un adpatateur d'authentification utilisant une base de données
                $authAdapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table_Abstract::getDefaultAdapter(), 'flux_users', 'username', 'password');

                //création de validateurs permettant de vérifier si certaines exigences sont respectées
                //par le login et le password
                $validatorLogin = new Zend_Validate();
                $validatorLogin->addValidator(new Zend_Validate_NotEmpty());
                $validatorLogin->addValidator(new Zend_Validate_StringLength(4));

                $validatorPassword = new Zend_Validate();
                $validatorPassword->addValidator(new Zend_Validate_NotEmpty());
                $validatorPassword->addValidator(new Zend_Validate_StringLength(4));

                //Vérification que le login et le password respectent les validateurs
                if ($validatorLogin->isValid($login) && $validatorPassword->isValid($password)) {
                    // Préparation de la requête d'authentification en indiquant l'identité et le crédit
                    $authAdapter->setIdentity($login);
                    $authAdapter->setCredential($password);
                    // Pour ne pas récupérer le compte invité
                    $authAdapter->setCredentialTreatment('SHA1(?) AND group_id > 0');

                    // Exécution de la requete d'authentification et enregistrement du résultat
                    $result = $this->_auth->authenticate($authAdapter);

                    // Si l'authentification a réussi
                    if ($result->isValid()) {

                        // Permet de récupérer l'objet utilisateur
                        $identity = $authAdapter->getResultRowObject('id');

                        // Stockage de l'identité sous forme d'objet
                        $this->_auth->getStorage()->write($identity);

                        // Permet de regénérer l'identifiant de la session
                        Zend_Session::regenerateId();

                        // Redirection
                        $this->_helper->_redirector('index', 'index');
                    }
                }
            }
        }

        $this->_redirect($this->view->url(array('controller' => 'login'), 'default', true));
    }

Dans ce code je stocke manuellement l'identifiant de la table afin d'avoir en persistance dans la session l'identifiant de l'utilisateur. Je précise aussi que le namespace est celui par defaut (donc 'Zend_Auth' si je me souviens bien), je ne me suis pas encore attaqué à cette étape mais je ne suis pas sûr d'en avoir besoin dans mon cas.

Comme j'ai pu le voir sur certain tutoriel j'ai tenté cette méthode :

Code:

[lang=php]// Permet de récupérer l'objet utilisateur
                        $identity = $authAdapter->getResultRowObject('id');

à la place de :

Code:

[lang=php]// Permet de récupérer l'objet utilisateur
                        $identity = $result->getIdentity();

Mais ceci me retournait le pseudo de l'utilisateur (soit c'est normal et certains tuto ne sont pas à jour, soit j'ai raté quelque chose (je penche plus pour la deuxième solution :p)).

Je ne détail pas ma methode de Logout puisqu'elle est classique à toutes celle que l'on croise.

Je possède une aide de vue qui me permet de gérer l'affichage de la partie de connexion suivant le statut de l'utilisateur :

Code:

[lang=php]function loggedUser() {
        
        $date = new Zend_Date();
        $this->_view->date = $date->toString('dd MMMM YYYY');
        
        $auth = Zend_Auth::getInstance();
        
        if ($auth->hasIdentity()) {
            // Création du lien logout à partir de l'aide de vue url
            $logoutUrl = $this->_view->url(array('controller' => 'login', 'action' => 'logout'), 'default', true);
            
            // Récupère l'identité de l'utilisateur
            $uid = $this->_view->escape($auth->getIdentity()->id);
            // Chaine qui sera affichée si l'utilisateur est connecté
            $link = 'id : ' . $uid . '<a href="' . $logoutUrl . '">Se déconnecter </a>';
        } else {
            
            // On affiche le formulaire dans l'entete
            $loginForm = new Application_Form_Login();
            
            $link = $loginForm;

        }
        
        return $link;
    }

J'ai modifié à la volé cette partie puisqu'elle contenait pas mal de code en commentaire et d'essais cependant il fonctionne chez moi.

Mon problème arrive maintenant; je souhaiterais en utilisant l'identifiant sotcké en session pouvoir récupérer à chaque requête HTTP récupérer les informations de l'utilisateur en base de données et les stocker de façon à ce qu'elles soient accessible dans chacun de mes contrôleurs de façon à ce que lorsque je modifie un droit sur le profil de l'utilisateur, celui-ci soit automatiquement mis à jour. A l'heure actuelle, l'utilisateur doit se déconnecter puis se reconnecter pour s'en apercevoir.

J'ai fait plusieurs test comme celui-ci que j'ai placé dans application/controllers/helpers. D'une part l'autoload ne fonctionne pas (j'ai peux être oublié quelque chose :

Code:

[lang=php]class Application_Controller_Helper_Profil extends Zend_Controller_Action_Helper_Abstract {

    /**
     * Perform helper when called as $this->_helper->Profil() from an action controller
     *
     * Proxies to {@link getProfil()}
     *
     * @return object user profil information
     */
    public function direct() {
        return $this->getProfil();
    }

    /**
     * Returns user profil information from session
     *
     * This method will try to retrieve current authenticated user profile information
     * from session and to return them as object. If data are not already stored in
     * session, they will be fetched from the database and  stored into it and finally
     * returned as object.
     *
     * @return object user profil information
     */
    public function getProfil() {
        Zend_Session::start(); // Ensuring that session is started
        $userProfileNamespace = new Zend_Session_Namespace('userProfileNamespace');

        if (!isset($userProfileNamespace->profile)) {
            /**
             * @var $db Zend_Db_Adapter_Abstract
             */
            $userMapper = new Application_Model_Mapper_User();
            $id = Zend_Auth::getInstance()->getIdentity()->id;
            
            $user = new Application_Model_User();
            $userMapper->find($id, $user);
            
            $userProfileNamespace->profil = $user;
        }

        return $userProfileNamespace->profile;
    }

    /**
     * Flush profil from session
     * @return void
     */
    public function flush() {
        Zend_Session::start();
        Zend_Session::namespaceUnset('userProfileNamespace');
    }

Malheureusement comme je n'arrive pas à charger l'helper de contrôler je n'ai pas pu tester ce bout de code mais je ne pense pas être très loin.

L'idée serait donc soit via ce code pouvoir le déclencher à chaque appel d'un contrôleur de l'application soit trouver une autre façon de faire mais que permettrait aussi soit à chaque appel de contrôleur soit plus tôt je ne me rend pas encore bien compte quelle méthode serait la plus performante.

Si quelqu'un peux m'aiguiller ça sera super sympa.

Par la suite je souhaiterai pouvoir utiliser les ACLs mais chaque chose en son temps smile

Merci d'avance

Orkin

Hors ligne

 

#2 09-12-2011 14:43:56

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

Salut,

Première chose sur ton premier bout de code : tu n'as pas besoin de recréer des validateurs. Tes validateurs et filtres doivent être directement dans l'objet Zend_Form. Le fait d'appeler isValid va justement appeler les validateurs. D'autres part, quand tu récupères les valeurs, il faut que tu les récupères en appelant la fonction getValue de l'objet Zend_Form, et non pas comme tu le fais depuis les variables POST (puisque tes variables ne sont pas filtrés ce qui peut poser problème niveau sécurité). Regarde bien la doc de Zend_Form à ce sujet.

Autrement, ce code là je n'y vois pas d'autres soucis.

Sinon la solution est effectivement un controller helper : tu pourras l'appeler dans tous tes contrôleurs et ainsi faire les traitements adéquats.

Pour que Zend puisse charger les controller helper il faut lui spécifier. Il faut que tu ajoutes donc la ligne suivante dans ton application.ini :

Code:

resources.frontController.actionHelperPaths.Application_Controller_Helper = APPLICATION_PATH . '/controllers/helpers'

Hors ligne

 

#3 09-12-2011 15:17:28

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

Bonjour Bakura, j'attendais une réponse avec impatience et je te remercie d'avoir pris le temps de me répondre.

Je prend note de tes conseils et procède aux modifications que tu me conseils de faire.

Je vais aussi modifier mon fichier application.ini pour lui indiquer où se trouve mes helpers.

J'aurais je pense d'autres questions par la suite mais je profite de celle-ci tant que je l'ai en tête. Avec cette méthode d'helper je vais pouvoir au moins charger partout les infos qui m'intéressent cependant j'imagine que le Zend Framework doit pouvoir m'éviter de réécrire l'appel au helper dans chaque contrôler ? Si oui pourrais-tu m'aiguiller sur la démarche à suivre.

Encore merci

Orkin

Je viens de faire les modifications, pour le formulaire ça fonctionne très bien. Merci.[/b]

Par contre j'ai toujours un soucis au niveau de mon helper de profil. En effet, l'autoloader ne parvient pas à le trouver et charger la classe du coup lors que j'essaie de l'instancier "normalement" ça ne fonctionne pas. Et j'ai la même chose lorsque je fais :

Code:

[lang=php]$this->_helper->getProfil()

J'ai fait un affichage des helpers disponible par mon contrôler et effectivement il n'y est pas :s.

J'ai essayé de le déclarer aussi directement dans mon bootstrap mais même chose.
Il doit y avoir une étape que je n'ai pas compris.

Orkin

Dernière modification par Orkin (09-12-2011 15:36:45)

Hors ligne

 

#4 09-12-2011 15:36:21

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

C'est-à-dire t'empêcher de réécrire l'appel au helper ?

J'espère ne pas faire d'erreur de syntaxe (je suis en ce moment beaucoup plus sur la bêta de ZF2, je commence à perdre les habitudes de la V1 big_smile), mais il suffit, dans tes actions, d'appeler l'aide par son nom. Par exemple, dans ta fonction init de ton contrôleur :

Code:

public function init()
{
    $this->profil = $this->getHelper('Profil');
}

Puis tu pourras appeler $this->profil dans toutes tes actions. Si tu souhaites éviter d'avoir à écrire cette fonction init dans tous tes contrôleurs, tu peux toujours faire une classe qui étend Zend_Controller_Action dans laquelle tu charges ton helper, puis tu fais étendre tous tes contrôleurs de cette nouvelle classe. Tu vois ce que je veux dire ?

Il y a une solution beaucoup plus classe avec ZF2 pour ce genre de problèmes via l'injecteur de dépendance, et je crois qu'il sera intégré dans une prochaine mise à jour de ZF1, mais en attendant il faut passer par l'une de ces deux techniques.

Hors ligne

 

#5 09-12-2011 15:41:09

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

bakura a écrit:

C'est-à-dire t'empêcher de réécrire l'appel au helper ?

Tu as très bien compris ce que je voulais dire. En effet c'est le système d'héritage. Je pensais justement à ce que tu proposes :

bakura a écrit:

Si tu souhaites éviter d'avoir à écrire cette fonction init dans tous tes contrôleurs, tu peux toujours faire une classe qui étend Zend_Controller_Action dans laquelle tu charges ton helper, puis tu fais étendre tous tes contrôleurs de cette nouvelle classe. Tu vois ce que je veux dire ?

J'ai juste pas osé m'aventurer là dedans par peur de faire n'importe quoi puisque même si je me fixe la barre un peu haute au début, je souhaite vraiment prendre les bonnes habitudes dès le début de façon à acquérir une méthode de développement seine et propre.

bakura a écrit:

Code:

public function init()
{
    $this->profil = $this->getHelper('Profil');
}

Puis tu pourras appeler $this->profil dans toutes tes actions.

Je vais essayer ça mais je l'avais déjà fait dans ma méthode d'action indexAction() et ça ne fonctionnait pas.

bakura a écrit:

Il y a une solution beaucoup plus classe avec ZF2 pour ce genre de problèmes via l'injecteur de dépendance, et je crois qu'il sera intégré dans une prochaine mise à jour de ZF1, mais en attendant il faut passer par l'une de ces deux techniques.

Oui et puis la version 2 sera pour la prochaine étape smile. Je pense qu'une fois que j'aurai vraiment bien compris ZF1 le 2 sera une adaptation mais beaucoup plus une formalité qu'un apprentissage de 0.

Edit :

Malheureusement ça ne fonctionne toujours pas j'ai ce message :

Code:

Message: Action Helper by name Profil not found

Je pensais que l'autoloader devait normalement le charger de façon "transparente" et qu'il serait possible d'appeler mon helper de cette façon puisque la methode "direct()" est définie.

Code:

[lang=php]$this->_helper->getProfil()

Dernière modification par Orkin (09-12-2011 15:44:16)

Hors ligne

 

#6 09-12-2011 15:53:54

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

Ce n'est pas getProfil, mais $this->_helper->profil(), qui fait appel à direct.

Si ya encore l'erreur (en fait, les composants ont pas tous été faits au même moment du développement de ZF, du coup la manière de les charger et de spécifier leur chemin changent suivant que c'est une aide de vue, une ressource d'application, un plugin de contrôleur... c'est assez relou), il faut aller chercher sur Google.

Hors ligne

 

#7 09-12-2011 16:02:06

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

J'ai tenté aussi cette méthode, rien à faire. La methode suivante dans la function init() ne génère le message d'erreur, et si je ne la met pas c'est celle lors de l'appel $this->_helper->profil().

Code:

[lang=php]$this->getHelper('Profil');

Ca fait déjà plusieurs jours que je cherche c'est pour ça que je commençais à venir demander de l'aide. Je te remercie pour tes conseils et je vais poursuivre mes recherches.

Orkin

Hors ligne

 

#8 12-12-2011 10:50:41

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

Bonjour, après réflexion et recherches j'ai créé mon propre contrôleur qui étend la classe Zend_Controller_Action et tous mes contrôleurs étende de mon propre contrôleur.

Dans ce contrôleur j'ai défini une méthode init qui me permet d'aller récupérer si l'utilisateur est authentifié les informations en base de données. Ca semble fonctionne pour ce que je souhaite faire.

J'ai vu qu'on pouvait passer par un plugin mais que c'était un peu plus lourd à mettre en place et plus "lourd" pour l'application.

Y a t-il une méthode plus "propre" que celle que j'ai mi en place ? Est-il préférable de m'orienter vers un plugin à plus ou moins long terme ?

Orkin

Hors ligne

 

#9 12-12-2011 12:14:04

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

A l'heure actuelle avec ZF1 c'est soit cette solution, soit le plugin. Reste sur cette solution, c'est plus simple que le plugin.

Hors ligne

 

#10 12-12-2011 13:55:09

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Zend 1.11][Zend_Auth et autre]Problème actualisation profil

Merci pour cette précision.

Cordialement

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages