isEmail($email)) throw new Exception('Byl zadán chybný E-mail.'); // Není dostatečně silné heslo (nesplňuje podmínky) if(!$this->checkPasswordInput($pass)) throw new Exception('Zadané heslo není dostatečně silné.'); // Je obsazený E-mail if(!$this->isEmailAvailable($email)) throw new Exception('Zadaný E-mail již někdo používá.'); // Šifrované heslo $hash_pass = password_hash($pass, PASSWORD_DEFAULT); $registered = $this->db->query(' INSERT INTO `users` (`email`, `first_name`, `last_name`, `password`, `token`) VALUES (?, ?, ?, ?, ?) ', $email, $fname, $lname, $hash_pass, $this->generateRandomBase64String()); // Nefunkční databáze if(!$registered) throw new Exception('Nastala chyba při komunikaci s databází'); return true; } /** * Příhlásí uživatele * * @param $email string E-mail * @param $pass string Heslo * @param $remember bool Pamatovat heslo? * * @return bool Úspěšně přihlášen? * * @throws Exception Nevyplněná pole * @throws Exception Chybné heslo */ public function login($email, $pass, $remember) { // Nějaké pole není vyplněno if(!isset($email) || !isset($pass)) throw new Exception('Některé pole není vyplněno.'); $user_from_db = $this->db->queryOne(' SELECT `password`, `token`, `name` FROM `users` WHERE `email` = ? ', $email); // Chybné heslo if(!password_verify($pass, $user_from_db['password'])) throw new Exception('Zadané heslo je chybné'); // Trvalé přihlášení (uložení tokenu do COOKIES) if(isset($remember)) setcookie('usertoken', $user_from_db['token'], time() + (86400 * 30), '/'); // Uložení dat do SESSION pro další používání $_SESSION['name'] = $user_from_db['name']; return true; } /** * Odhlásit uživatele * * @return bool Úspěšně odhlášeno? * * @throws Exception Chybějící token */ public function logout() { // Chybí token if(!isset($_COOKIE['usertoken'])) throw new Exception('Chybí uživatelský token.'); setcookie('usertoken', '', time()-1, '/'); } /** * Je uživatel přihlášený? * * @return bool Je uživatel přihlášen? */ public function isLogged() { // Defaultně je přihlášení chybné $return = false; // Klient vlastní token if(isset($_COOKIE['usertoken'])) { $user_from_db = $this->db->queryOne(' SELECT `token` FROM `users` WHERE `email` = ? ', $_COOKIE['useremail']); // Je token správný? $return = $_COOKIE['usertoken'] == $user_from_db['token']; } return $return; } /** * Ověří sílu hesla * * @param $password string Vstupní heslo k ověření * * @return bool Je dostatečně silné? */ private function checkPasswordInput($password) { $return = false; if(strlen($password) > 6) $return = true; return $return; } /** * Ověří, jestli je jedná o E-mail * * @param $input string Vstupní text * * @return bool Jedná se o E-mail? */ private function isEmail($input) { return (bool) filter_var($input, FILTER_VALIDATE_EMAIL); } /** * Ověří, jestli je E-mail volný * * @param $email string Vstupní E-mail k ověření * * @return bool Je dostupný? */ private function isEmailAvailable($email) { $return = false; if($this->isEmail($email)) { $query = $this->db->queryOne(' SELECT `email` FROM `users` WHERE `email` = ? ', $email); // Pokud nebyl E-mail nalezen v databázi, je volný (dotaz vrátil false) if(!$query) $return = true; } return $return; } /** * Ošetří výstup * * @var $string string Vstupní řetezec * * @return string Ošetřený řetezec */ private function treatOutput($string) { // ENT_QUOTES zajituje ošetření i jednoduchých uvozovek (') return htmlspecialchars($string, ENT_QUOTES); } /** * Vygeneruje náhodný řetezec o n znacích (n = length) * * @param int $length Délka řetězce * * @return string Náhodný řetězec */ private function generateRandomBase64String($length = 32) { /* Je vyžadován MCRYPT_DEV_URANDOM (od PHP 5.3)! */ $binary_length = (int) ($length * 3 / 4 + 1); $random_binary_string = mcrypt_create_iv($binary_length, MCRYPT_DEV_URANDOM); $random_base_64_string = base64_encode($random_binary_string); return substr($random_base_64_string, 0, $length); } }