Bonjour à tous,
[b]j'ai repris le système du MVC dans "Développer un site de A à Z" comme base à ensuite adapter.[/b]
En autres, j'ai voulu faire évoluer un système d'utilisateurs (permissions, infos, etc) mais surtout connexion persistante par cookies.
J'ai un système qui semble fonctionner correctement, mais me semble assez "moche" dans sa répartition au sein de MVC et aimerais vos avis et conseils à ce sujet si possible.
Comment ça marche?
Mon soucis est sur le test du cookie.
Je lance une méthode dans le Dispatcher
-> Dispatcher qui crée un Controller "User" et lui demande de faire le travail
-> User qui va demander a l'Objet Session de trouver le cookie, d'en extraire l'ID utilisateur
-> User qui va récupérer l'utilisateur dans la BDD par l'intermédiaire de son Model et l'ID donné
-> User qui va passer à Session les infos requises pour comparer le cryptage cookie avec les infos de l'utilisateur
-> USer qui va enfin connecter l'utilisateur si tout va bien (en envoyant a Session les infos à stocker en session.
En version plus détaillée avec mon code ça donne:
Pour tester si il y a un cookie, lorsque le Dispatcher charge le controller lié à la requete de l'url par la méthode LoadController(), j'ai rajouté un bout de code qui lance le tout, enfermé dans un test sur une variable de session indépendante pour éviter de le faire à chaque chargement.
[code]
public function loadController(){
$name = ucfirst($this->request->controller).'Controller';
$file = ROOT.DS.'controller'.DS.$name.'.php';
if(!file_exists($file)) {
$this->error('Controller "'.$name.'" not found', 'e001');
}
require $file;
$controller = new $name($this->request);
$controller->Session = new Session();
$controller->Form = new Form($controller);
// test session user from cookies (if not already done)
if($controller->Session->read('cookieinit') != 'done') {
// we use the Controller method to load an other controller for simplicity
$controller->request('Users','findPersistantLogin');
$controller->Session->write('cookieinit', 'done');
}
//
return $controller;
}
[/code]
Le Controller créé et la méthode lancé vont pouvoir chercher les informations utilisateur dans la BDD et demander à l'Objet Session les infos du cookie
[code]
public function findPersistantLogin() {
if(!$this->Session->isLogged()){
$unsafeCookie = $this->Session->explodeUserCookie();
if(is_array($unsafeCookie) && is_numeric($unsafeCookie[0])) {
// fetch user from ID found in cookie
$this->loadModel('User');
$user = $this->User->findFirst(array(
'fields' => 'User.id as id,User.login as login,User.password as password, User.screenname as screenName,Role.name as roleName,Role.slug as roleSlug,Role.level as roleLevel',
'join' => array('roles as Role' => 'Role.id=User.role'),
'conditions' => array('id' => $unsafeCookie[0])
));
// if match, test cookie code with fetched data
//
if(!empty($user) && isset($unsafeCookie[1]) && $this->Session->testCookie($unsafeCookie[1], $user->login, $user->password)) {
$this->Session->loginUser($user, true);// arg2 = true when storing cookie
}
else {
$this->Session->logoutUser();
}
$this->redirect('');
}
}
}
[/code]
[code]
public function setUserCookie($code = false) {
if($code) {
setcookie('auth', $code, time() + 3600 24 3, '/', $_SERVER['SERVER_NAME'], false, true);
} else {
setcookie('auth', '', time() - 3600, '/', $_SERVER['SERVER_NAME'], false, true);
}
}
private function getRawCookie() {
return (isset($_COOKIE['auth']))? $_COOKIE['auth'] : false;
}
private function generateCookieCode($login, $password) {
return sha1($login.'azer'.$password.'tyui'.$_SERVER['REMOTE_ADDR']);
}
private function buildRawCookie($id, $code) {
return $id.'----'.$code;
}
public function explodeUserCookie() {
$auth = $this->getRawCookie();
if($auth) {
$auth = explode('----', $auth);
if(isset($auth[1]) && is_numeric($auth[0])) {
return $auth;
}
}
// clear cookie
$this->setUserCookie(false);
return false;
}
public function testCookie($code, $login, $password) {
// compare fetched data with cookie code
if($code == $this->generateCookieCode($login, $password)) {
// log user in session
$this->write('User', $data);
// refresh cookie
$this->setUserCookie($this->buildRawCookie($auth[0], $auth[1]));
// end method here
return true;
}
// clear cookie
$this->setUserCookie(false);
return false;
}
[/code]
Voila en gros tout mon système...
Je ne suis pas certain que le lancement initial dans le dispatcher->loadController() soit le plus logique/propre. J'ai du mal aussi à choisir dans quel sens lancer le tout entre le controller User et la classe Session, etc.
Tout marche au final, mais j'aimerais des conseils sur ce qui semblerait le mieux pour un systeme MVC "logique" et "propre" :)