Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /**
- * Created by PhpStorm.
- * User: vitaliy
- * Date: 10.11.17
- * Time: 16:39
- */
- class Auth
- {
- private $db;
- public function __construct()
- {
- $this->db = new \PDO("sqlite:".dirname(__FILE__)."/db/ttoeDB.db");
- }
- /** Проверка, занят ли логин
- * @param string $username
- * @return bool TRUE - если да, FALSE - если нет
- */
- public function userExists(string $username)
- {
- $query = $this->db->prepare("SELECT COUNT(id) FROM accounts WHERE username = ?");
- $query->execute([$username]);
- return (bool)$query->fetchColumn();
- }
- private function genRandomString(){
- $string = "";
- $chars = 'qwertyuiopasdfghjklzxcvbnm12347890';
- $len = rand(12,24);
- for ($i = 0; $i < $len; $i++){
- $string .= substr($chars, rand(0, strlen($chars)-1), 1);
- }
- return $string;
- }
- /** Подтверждение почты (не заверщено!)
- * @param string $email
- * @return bool
- */
- private function sendVerificationMail(string $email){
- $code = $this->genRandomString();
- $query = $this->db->prepare("UPDATE accounts SET verify_code = '?' WHERE email = '?'");
- return $query->execute();
- //TODO: реализовать отправку письма
- }
- /** Регистрация
- * @param $email - эл почта
- * @param $username - имя пользователя(логин/ник)
- * @param $password - пароль
- * @return array $result - результат выполнения
- * <p>
- * Если $result['result'] == false, то коды ошибок представлены в массиве $result['err']
- *
- * <ul style="list-style-type:none"><b>Доступные коды ошибок:</b>
- * <li><b>0</b> - Неизвестная ошибка (БД?)</li>
- * <li><b>1</b> - Пользователь уже существует</li>
- * </ul>
- * </p>
- */
- public function register($email, $username, $password)
- {
- $result = [
- 'result' => true,
- 'err' => [],
- ];
- if ($this->userExists($username)) {
- $result['result'] = false;
- $result['err'][] = '1';
- }
- $userdata = [
- 'username' => strtolower($username),
- 'email' => $email,
- 'password' => password_hash($password, PASSWORD_DEFAULT),
- ];
- if ($result['result']) {
- if (!$this->db->prepare("INSERT INTO ACCOUNTS (username, email, password) VALUES (?,?, ?);")->execute(
- [
- $userdata['username'],
- $userdata['email'],
- $userdata['password']
- ]
- )) {
- $result['result'] = false;
- $result['err'][] = '0';
- }else{
- $this->sendVerificationMail($userdata['email']);
- }
- }
- return $result;
- }
- /** Получение массива пользовательских данных
- * @param $username
- * @return bool|mixed FALSE - если пользователь не существует, в ином случае массив с данными пользователя
- */
- public function getUserData($username)
- {
- if($this->userExists($username)){
- $query = $this->db->prepare("SELECT * FROM accounts WHERE username = ?");
- $query->execute([$username]);
- return $query->fetch(PDO::FETCH_ASSOC);
- }else{
- return FALSE;
- }
- }
- /** Добавление нового токена
- * @param int $userid ID пользователя
- * @return bool|string FALSE - если ошибка в бд или пользователь не существует, иначе строка с токеном
- */
- public function addToken(int $userid)
- {
- $userExists = (bool)$this->db->query("SELECT COUNT(id) FROM accounts WHERE id = $userid")->fetchColumn();
- if(!$userExists){
- return false;
- }
- $token = $this->genRandomString();
- $token_exp = time()+(60*60*24*7);
- if($this->db->prepare("INSERT INTO tokens (token, token_exp, user_id) VALUES (?, ?, ?)")->execute([$token, $token_exp, $userid])){
- return $token;
- }else{
- return false;
- }
- }
- /** Удаление устаревших токенов и таблицы токенов
- * @param int $userid ID пользователя
- * @return bool TRUE - если успешно, FALSE - если ошибка бд
- */
- private function destroyExpiredTokens(int $userid){
- return ($this->db->query("DELETE FROM tokens WHERE token_exp < ".time()." AND user_id = $userid") !==FALSE)?true:false;
- }
- /** Закрытие остальных сессий
- * Отождествляет кнопку "закрыть все остальные сессии"
- * @param string $curr_token текущий токен
- * @param bool $destroy Если TRUE - уничтожает остальные сесси, ставит время истечения равное текущему
- * т.е они просто истекают
- * @return bool
- */
- public function closeOtherSess(string $curr_token, bool $destroy = false)
- {
- if(!$this->isTokenValid($curr_token)){
- return false;
- }
- $curr_token = $this->db->quote($curr_token);
- $userID = $this->db->query("SELECT user_id FROM tokens WHERE token = $curr_token");
- if($userID !== false){
- $userID = $userID->fetchColumn();
- $allTokens = $this->db->query("SELECT * FROM tokens WHERE user_id = $userID AND token != $curr_token");
- if($allTokens !==false){
- foreach ($allTokens->fetchAll(PDO::FETCH_ASSOC) as $item) {
- $this->expireToken($item['token']);
- }
- if($destroy){
- $this->destroyExpiredTokens($userID);
- }
- return true;
- }
- }
- return false;
- }
- /** Проверка валидности токена
- * @param $token строка токена
- * @return bool
- */
- public function isTokenValid($token)
- {
- $token = $this->db->quote($token);
- $tokendata = $this->db->query("SELECT * FROM tokens WHERE token = $token");
- if($tokendata !== false){
- $tokendata = $tokendata->fetch(PDO::FETCH_ASSOC);
- if($tokendata['token_exp'] < time()){
- return false;
- }else{
- return true;
- }
- }else{
- return false;
- }
- }
- /** Форсирование окончания действия токена
- * @param $token строка токена
- * @return bool FALSE - если токен не существует, или ошибка бд
- */
- private function expireToken($token){
- $token = $this->db->quote($token);
- $tokenExists = (bool)$this->db->query("SELECT COUNT(token) FROM tokens WHERE token = $token")->fetchColumn();
- if(!$tokenExists){
- return false;
- }
- return ($this->db->query("UPDATE tokens SET token_exp = ".(time()-1)." WHERE token = $token") !== FALSE)?true:false;
- }
- /** Проверка, залогинен ли юзер
- * @return bool
- */
- public function isLogged()
- {
- $result = false;
- if(isset($_COOKIE['token'])){
- if($this->isTokenValid($_COOKIE['token'])){
- $result = true;
- }
- }
- return $result;
- }
- /** Авторизация
- * @param $username - имя пользователя
- * @param $password - пароль
- * @return array
- * <p>
- * Если $result['result'] == false, то коды ошибок представлены в массиве $result['err']
- *
- * <ul style="list-style-type:none"><b>Доступные коды ошибок:</b>
- * <li><b>0</b> - неверная пара (логин, пароль)</li>
- * <li><b>1</b> - уже авторизован</li>
- * </ul>
- * </p>
- */
- public function auth($username, $password)
- {
- $username = strtolower($username);
- $result = [
- 'result' => true,
- 'err' => [],
- ];
- if(!$this->userExists($username)){
- $result['result'] = false;
- $result['err'][] = '0';
- }else{
- if(!$this->isLogged()){
- $userdata = $this->getUserData($username);
- if(password_verify($password, $userdata['password'])){
- $this->destroyExpiredTokens($userdata['id']);
- setcookie('token', $this->addToken($userdata['id']));
- }else{
- $result['result'] = false;
- $result['err'][] = '0';
- }
- }else{
- $result['result'] = false;
- $result['err'][] = '1';
- }
- }
- return $result;
- }
- /** Выход
- * @return array
- * <p>
- * Если $result['result'] == false, то коды ошибок представлены в массиве $result['err']
- *
- * <ul style="list-style-type:none"><b>Доступные коды ошибок:</b>
- * <li><b>0</b> - пользователь не залогинен</li>
- * </ul>
- * </p>
- */
- public function logout()
- {
- $result = [
- 'result' => false,
- 'err' => [],
- ];
- if(!$this->isLogged()){
- $result['err'][] = 0;
- return $result;
- }
- if(isset($_COOKIE['token'])){
- $this->expireToken($_COOKIE['token']);
- }
- setcookie("token", "");
- $result['result'] = true;
- return $result;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement