Overview

Packages

  • Auth
  • Config
  • Controller
  • Date
  • Db
  • Feed
    • Abstract
    • Writers
  • File
    • Decorator
  • Form
    • Element
  • Image
  • Log
    • Writer
  • Net
    • Exception
  • None
  • PHP
  • PHPMailer
  • Session
  • Util
  • Validate
    • Validator
  • Zend
    • Registry

Classes

  • Auth_ACL
  • Auth_Auth
  • Auth_Bcrypt
  • Auth_Util
  • Auth_WithRole
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Pry Framework
  5:  *
  6:  * LICENSE
  7:  *
  8:  * This source file is subject to the new BSD license that is bundled
  9:  * with this package in the file LICENSE.txt.
 10:  * 
 11:  * @version $Revision: 276 $
 12:  */
 13: 
 14: /**
 15:  * Identification d'utilisateur via BDD
 16:  * 
 17:  * <code>
 18:  * // Exemple d'identification
 19:  * $sess = Session_Session::getInstance('nomSession',10);
 20:  * $auth = new Auth($sess);
 21:  * $auth->setUserTable('user');
 22:  * $auth->setUserField('login');
 23:  * $auth->setPwdField('pwd');
 24:  * $auth->setHashRounds(10);
 25:  * $auth->login($_POST['login'],$_POST['mdp']);
 26:  * if(!$auth->error)
 27:  * {
 28:  *   if($auth->isLogged())
 29:  *   {
 30:  *     echo 'Connnecté';
 31:  *     print_r($_SESSION);
 32:  *   }
 33:  *   else
 34:  *     echo 'pas Connecté';
 35:  *   }
 36:  * else
 37:  * {
 38:  *   echo $auth->displayError();
 39:  * }
 40:  * </code>
 41:  * 
 42:  * @category Pry
 43:  * @package Auth
 44:  * @version 1.4.0 
 45:  * @author Olivier ROGER <oroger.fr>
 46:  * @see http://stackoverflow.com/questions/549/the-definitive-guide-to-forms-based-website-authentication#477579  
 47:  * 
 48:  */
 49: class Auth_Auth
 50: {
 51:     const NO_ERROR      = 0;
 52:     const ERROR_LOG     = 1;
 53:     const ERROR_PASS    = 2;
 54:     const ERROR_TABLE   = 3;
 55:     const ERROR_FIELD   = 4;
 56: 
 57:     /**
 58:      * Objet pour accès bdd
 59:      * @access private
 60:      * @var Zend_Db_Adapter_Abstract
 61:      */
 62:     private $oDB;
 63: 
 64:     /**
 65:      * Type d'erreur rencontrée
 66:      * @access private
 67:      * @var int $errorType
 68:      */
 69:     private $errorType;
 70: 
 71:     /**
 72:      * Message d'erreur
 73:      * @access private
 74:      * @var string $errorMsg
 75:      */
 76:     private $errorMsg;
 77: 
 78:     /**
 79:      * Table des utilisateurs
 80:      * @access public
 81:      * @var string $userTable
 82:      */
 83:     private $userTable;
 84: 
 85:     /**
 86:      * Champs du nom d'utilisateur
 87:      * @access public
 88:      * @var string $userField
 89:      */
 90:     private $userField;
 91: 
 92:     /**
 93:      * Champs du mot de passe
 94:      * @access public
 95:      * @var string $pwdField
 96:      */
 97:     private $pwdField;
 98:     
 99:     /** Champs contenant le token d'autologin */
100:     private $autologTokenField;
101:     
102:     /** Nombre d'itération pour l'algo bcrypt */
103:     private $hashRounds;
104: 
105:     /**
106:      * Connexion automatique
107:      * @access public
108:      * @var boolean $autoLogin
109:      */
110:     private $autoLogin;
111: 
112:     /**
113:      * Option des cookies
114:      * @access public
115:      * @var array $cookieOption
116:      */
117:     private $cookieOption;
118: 
119:     /**
120:      * Page de redirection en cas d'erreur
121:      * @access public
122:      * @var string $redirectError
123:      */
124:     private $redirectError;
125: 
126:     /**
127:      * Redirection en cas de succès
128:      * @access public
129:      * @var string $redirect
130:      */
131:     private $redirect;
132:     
133:     /**
134:      * Durée de vie de l'authentification
135:      * @var type 
136:      */
137:     private $timeOutSession;
138: 
139:     /**
140:      * Erreur lors de l'identification
141:      *
142:      * @var boolean $error
143:      */
144:     public $error;
145: 
146:     /**
147:      * Session
148:      *
149:      * @var Session_Session
150:      */
151:     private $session;
152: 
153:     /**
154:      * Constructeur
155:      * 
156:      * @param Zend_Db_Adapter_Abstract $db Objet Zend Db
157:      * @param Session_Session $session
158:      * @access public
159:      */
160:     public function __construct(Session_Session $session,Zend_Db_Adapter_Abstract $db)
161:     {
162:         $this->oDB          = $db;
163:         $this->userTable    = 'user';
164:         $this->userField    = 'login';
165:         $this->pwdField     = 'password';
166:         $this->pwdHash      = 'md5';
167:         $this->autoLogin    = false;
168:         $timeTTL = time() + (365 * 24 * 3600);
169:         $this->cookieOption = array(
170:             'name' => 'loginCookie',
171:             'ttl' => $timeTTL
172:         );
173:         $this->timeOutSession   = 0;
174:         $this->redirectError    = 'index.php';
175:         $this->redirect         = (!empty($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
176:         $this->error            = false;
177:         $this->errorType        = self::NO_ERROR;
178:         $this->errorMsg         = '';
179:         $this->session          = $session;
180: 
181:         if (!isset($session->AC_lastAct))
182:         {
183:             $session->AC_connected  = 0;
184:             $session->AC_lastAct    = 0;
185:         }
186:     }
187: 
188:     /**
189:      * Identification classique via formulaire
190:      *
191:      * @param string $login
192:      * @param string $pass
193:      */
194:     public function login($login, $pass)
195:     {
196:         if ($this->checkUser($login))
197:             if ($this->checkPass($login, $pass))
198:             {
199:                 $this->startSession();
200:                 $this->session->AC_connected    = true;
201:                 $this->session->AC_lastAct      = time();
202:                 if ($this->autoLogin)
203:                 {
204:                     $this->createCookie($login);
205:                 }
206:             }
207:             else
208:                 $this->displayError();
209:         else
210:             $this->displayError();
211:     }
212: 
213:     public function logout()
214:     {
215:         $this->destroySession();
216:         $this->destroyCookie();
217:     }
218: 
219:     /**
220:      * Vérifie si l'utilisateur est identifié
221:      *
222:      * @return boolean
223:      */
224:     public function isLogged()
225:     {
226:         $lastActivity = time() - $this->session->AC_lastAct;
227:         // Cas 1 - Session existante illimité
228:         if ($this->session->AC_connected === true && $this->timeOutSession == 0)
229:         {
230:             $this->session->AC_lastAct = time();
231:             if ($lastActivity > 300)
232:                 $this->session->refresh();
233:             return true;
234:         }
235:         // Cas 2 - Session limité mais existante et TTL non dépassé
236:         elseif ($this->session->AC_connected === true && $lastActivity < $this->timeOutSession && $this->timeOutSession != 0)
237:         {
238:             $this->session->AC_lastAct = time();
239:             if ($lastActivity > 300)
240:                 $this->session->refresh();
241:             return true;
242:         }
243:         // Cas 3 - Session limité mais existante et TTL dépassé
244:         elseif ($this->session->AC_connected === true && $lastActivity > $this->timeOutSession && $this->timeOutSession != 0)
245:         {
246:             $this->logout();
247:             return false;
248:         }
249:         // Cas 4 - Session inexistante mais autologin
250:         elseif (isset($this->session->AC_connected) && !$this->session->AC_connected && $this->autoLogin)
251:         {
252:             if ($this->loginCookie())
253:                 return true;
254:             else
255:                 return false;
256:         }
257:         // Tout autre cas
258:         else
259:         {
260:             return false;
261:         }
262:     }
263: 
264:     /**
265:      * Affichage des erreurs
266:      *
267:      * @return string
268:      */
269:     public function displayError()
270:     {
271:         switch ($this->errorType)
272:         {
273:             case self::ERROR_LOG:
274:                 $this->errorMsg = 'Identifiant incorrect';
275:                 break;
276:             case self::ERROR_PASS:
277:                 $this->errorMsg = 'Mot de passe incorrect';
278:                 break;
279:         }
280:         return $this->errorMsg;
281:     }
282: 
283:     /**
284:      * Identification via cookie
285:      *
286:      * @return boolean
287:      */
288:     private function loginCookie()
289:     {
290:         if (isset($_COOKIE['' . $this->cookieOption['name'] . '']))
291:         {
292:             $datas      = $_COOKIE['' . $this->cookieOption['name'] . ''];
293:             $pos        = strripos($datas, '|');
294:             $login      = substr($datas, 0, $pos);
295:             $token      = substr($datas, $pos + 1);
296: 
297:             if ($this->checkUser($login))
298:             {
299:                 $prepare    = $this->oDB->prepare('SELECT ' . $this->autologTokenField . ' FROM ' . $this->userTable . ' WHERE ' . $this->userField . ' = :logCookie');
300:                 $prepare->execute(array(':logCookie' => $login));
301:                 $data       = $prepare->fetchColumn();
302: 
303:                 if ($token == $data)
304:                 {
305:                     $this->startSession();
306:                     $this->session->AC_connected    = true;
307:                     $this->session->AC_lastAct      = time();
308:                     //Mise à jour du cookie et du token d'autologin
309:                     $this->destroyCookie();
310:                     $this->createCookie($login);
311:                     return true;
312:                 }
313:                 else
314:                 {
315:                     $this->error        = true;
316:                     $this->errorType    = self::ERROR_PASS;
317:                     $this->destroyCookie();
318:                     $this->displayError();
319:                 }
320:             }
321:             else 
322:             {
323:                 $this->destroyCookie();
324:                 $this->displayError();
325:             }
326:                 
327:         }
328:         return false;
329:     }
330: 
331:     /**
332:      * Démarrage session si innexistante
333:      *
334:      */
335:     public function startSession($name='acauth')
336:     {
337:         if (empty($this->session))
338:             $this->session = Session_Session::getInstance($name, $this->timeOutSession);
339:     }
340: 
341:     /**
342:      * Création du cookie avec salage du mdp avec le token
343:      *
344:      * @param string $login
345:      */
346:     private function createCookie($login)
347:     {
348:         $token  = $this->generateRandomToken();
349:         $value  = $login.'|'.$token;
350:         setcookie($this->cookieOption['name'], $value, $this->cookieOption['ttl']);
351:         
352:         //Mise à jour du token dans la base
353:         $prep = $this->oDB->prepare('UPDATE '.$this->userTable.' SET '.$this->autologTokenField.' = :token WHERE '.$this->userField.' = :user');
354:         $prep->execute(array(
355:             ':token' => $token,
356:             ':user'  => $login
357:         ));
358:     }
359:     
360:     private function generateRandomToken()
361:     {
362:         $token = '';
363:         $char = '+-*$=)_!?./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
364:         for($i = 0; $i < 35; $i++)
365:             $token .= $char[mt_rand(0,72)];
366:         
367:         return sha1($token);
368:     }
369: 
370:     /**
371:      * Destruction de la session et de toute les variables associées
372:      *
373:      */
374:     private function destroySession()
375:     {
376:         $this->session->destroy();
377:     }
378: 
379:     /**
380:      * Destruction du cookie
381:      *
382:      */
383:     private function destroyCookie()
384:     {
385:         setcookie($this->cookieOption['name'], NULL, time() - 1);
386:     }
387: 
388:     /**
389:      * Vérification de l'identifiant
390:      *
391:      * @param string $user
392:      * @return boolean
393:      */
394:     private function checkUser($user)
395:     {
396:         $prepare = $this->oDB->prepare('SELECT ' . $this->userField . ' FROM ' . $this->userTable . ' WHERE ' . $this->userField . ' = :user');
397:         $prepare->execute(array(':user' => $user));
398:         if ($prepare->fetchColumn())
399:             return true;
400:         else
401:         {
402:             $this->error = true;
403:             $this->errorType = self::ERROR_LOG;
404:             return false;
405:         }
406:     }
407: 
408:     /**
409:      * Vérification du mot de passe
410:      *
411:      * @param string $login Identifiant
412:      * @param string $pass
413:      * @access private
414:      * @return boolean
415:      */
416:     private function checkPass($login, $pass)
417:     {
418:         $prepare    = $this->oDB->prepare('SELECT ' . $this->pwdField . ' FROM ' . $this->userTable . ' WHERE ' . $this->userField . ' = :login');
419:         $prepare->execute(array(':login' => $login));
420:         $hash = $prepare->fetchColumn();
421:         
422:         if (Auth_Bcrypt::check($pass, $hash))
423:             return true;
424:         else
425:         {
426:             $this->error = true;
427:             $this->errorType = self::ERROR_PASS;
428:             return false;
429:         }
430:     }
431: 
432:     /**
433:      * Hash le mot de pass dans l'algo souhaité
434:      *
435:      * @param string $algo
436:      * @param string $pass
437:      * @return string
438:      */
439:     private function hashPass($pass)
440:     {
441:         /*if ($this->pwdHash != 'nohash')
442:             return hash($this->pwdHash, $pass);
443:         else
444:             return $pass;*/
445:         
446:         $bCrypt = new Auth_Bcrypt($this->hashRounds);
447:         return $bCrypt->hash($pass);
448:     }
449: 
450:     /**
451:      * Retourne l'erreur si existante
452:      *
453:      * @since 1.0.5
454:      * @return int
455:      */
456:     public function getErrorType()
457:     {
458:         return $this->errorType;
459:     }
460:     
461:     /**
462:      * Défini le nom de la table contenant les comptes utilisateurs
463:      * @param string $userTable 
464:      */
465:     public function setUserTable($userTable)
466:     {
467:         $this->userTable = $userTable;
468:     }
469:     
470:     /**
471:      * Défini le champs contenant l'identifiant unique par utilisateur
472:      * @param string $userField 
473:      */
474:     public function setUserField($userField)
475:     {
476:         $this->userField = $userField;
477:     }
478:     
479:     /**
480:      * Défini le champs contenant le hash du mot de passe
481:      * @param string $pwdField 
482:      */
483:     public function setPwdField($pwdField)
484:     {
485:         $this->pwdField = $pwdField;
486:     }
487:     
488:     /**
489:      * Défini le champs contenant le token utilisé par le cookie d'autologin
490:      * @param string $autologTokenField 
491:      */
492:     public function setAutologTokenField($autologTokenField)
493:     {
494:         $this->autologTokenField = $autologTokenField;
495:     }
496:     
497:     /**
498:      * Défini le nombre d'itération utilisé dans le cryptage Bcrypt du mot de passe
499:      * @param int $hashRounds 
500:      */
501:     public function setHashRounds($hashRounds)
502:     {
503:         $this->hashRounds = $hashRounds;
504:     }
505:     
506:     /**
507:      * Active ou non l'autologin
508:      * @param boolean $autoLogin 
509:      */
510:     public function setAutoLogin($autoLogin)
511:     {
512:         $this->autoLogin = $autoLogin;
513:     }
514:     
515:     /**
516:      * Défini les options du cookie d'autologin.
517:      * 
518:      * @param array $cookieOption Doit contenir les clés "name" (string) et ttl (int) durée de vie en seconde
519:      */
520:     public function setCookieOption($cookieOption)
521:     {
522:         $this->cookieOption = $cookieOption;
523:     }
524:     
525:     /**
526:      * Défini en seconde la durée de vie de l'authentification
527:      * @param type $timeout 
528:      */
529:     public function setTimeoutSession($timeout)
530:     {
531:         $this->timeOutSession = $timeout;
532:     }
533: 
534: 
535: 
536: }
537: 
538: ?>
Pry Framework API documentation generated by ApiGen 2.6.1