Как сделать авторизацию на PHP? Пишем авторизацию пользователя
Внимание! Данная статья является устаревшей и носит исключительно ознакомительный характер. Если вас интересует авторизация на PHP, рекомендуем прочитать следующий материал по использованию готовых библиотек авторизации.
В этой статье вы узнаете, как сделать PHP-авторизацию (authentication) на сайте с помощью данных, полученных от пользователя при регистрации. Будем использовать таблицу MySQL, а сама PHP-авторизация будет работать с применением сессий и cookie.
В первую очередь нужно сверстать главную страницу веб-сайта, поместив её в корне в папку template. Для этого создаём файл index.html с формой ввода логина и пароля, кнопкой «Вход», вот её код:
<form action="/" method="post"> Логин: <input type="text" name="login" /> Пароль: <input type="password" name="password" /> <input type="submit" value="Войти" name="log_in" /> </form>
Мы используем метод передачи post, который необходим. Нам ведь не нужно, чтобы в процессе PHP-авторизации пароль и логин «светились» в адресной строке.
Когда форма готова, создаём главный контроллер — наиболее важный файл сайта, лежащий в корне — index.php. Как раз он и будет запускаться во время входа. Код выглядит следующим образом:
<? include ('lib/connect.php'); //подключаемся к БД include ('lib/module_global.php'); //подключается файл с глобальными функциями if($_GET['action'] == "out") out(); //если передана переменная action, «разавторизируем» пользователя if (login()) //вызываем функцию login, которая определяет, авторизирован пользователь или нет { $UID = $_SESSION['id']; //если пользователь авторизирован, присваиваем переменной $UID его id $admin = is_admin($UID); //определяем, админ ли пользователь } else //если пользователь не авторизирован, проверяем, была ли нажата кнопка входа на сайт { if(isset($_POST['log_in'])) { $error = enter(); //функция входа на сайт if (count($error) == 0) //если ошибки отсутствуют, авторизируем пользователя { $UID = $_SESSION['id']; $admin = is_admin($UID); } } } include ('tpl/index.html'); //подключается файл с формой ?>
Теперь разберёмся подробнее, как всё работает.
В первых 3 строках просто подключаются файлы с функциями, необходимыми для дальнейшего использования в коде. О них поговорим потом. Далее проверяем, был ли передан get-параметр
<a href="/?action=out">Выход</a>
Потом у нас идёт условие, которое проверяет, авторизован ли ты (if (login())). То есть функция возвращает нам true, если юзер вошёл на сайт. В противном случае возвращается false. Когда вернулось true, в переменную $UID записывается id юзера. Что касается переменной $admin, то в неё пишется результат работы функции
Итак, форму PHP-авторизации можно вывести следующим условием:
<? If($UID) //если переменной нет, выводим форму {?> <form action="/" method="post"> Логин: <input type="text" name="login" /> Пароль: <input type="password" name="password" /> <input type="submit" value="Войти" name="log_in" /> </form> <?} ?>
Аналогичная ситуация и с переменной $admin. Последний код тоже можно поместить в файл с формой.
Если функция
if(isset($_POST['log_in']))
Если это так, запускается функция
Давайте посмотрим на алгоритм работы:
А теперь рассмотрим все функции, вызываемые в коде. Вот функция входа на сайт:
function enter () { $error = array(); //массив для ошибок if ($_POST['login'] != "" && $_POST['password'] != "") //если поля заполнены { $login = $_POST['login']; $password = $_POST['password']; $rez = mysql_query("SELECT * FROM users WHERE login=$login"); //запрашивается строка из базы данных с логином, введённым пользователем if (mysql_num_rows($rez) == 1) //если нашлась одна строка, значит такой юзер существует в базе данных { $row = mysql_fetch_assoc($rez); if (md5(md5($password).$row['salt']) == $row['password']) //сравнивается хэшированный пароль из базы данных с хэшированными паролем, введённым пользователем { //пишутся логин и хэшированный пароль в cookie, также создаётся переменная сессии setcookie ("login", $row['login'], time() + 50000); setcookie ("password", md5($row['login'].$row['password']), time() + 50000); $_SESSION['id'] = $row['id']; //записываем в сессию id пользователя $id = $_SESSION['id']; lastAct($id); return $error; } else //если пароли не совпали { $error[] = "Неверный пароль"; return $error; } } else //если такого пользователя не найдено в базе данных { $error[] = "Неверный логин и пароль"; return $error; } } else { $error[] = "Поля не должны быть пустыми!"; return $error; } }
Сначала функция проверит, а заполнено ли поле для ввода пароля и логина для PHP-аутентификации. Если да, работа программы продолжается, в противном случае в массив
Но если работа функции
Пароли сравниваются не в чистом виде, т. к. в базе данных они хэшированы функцией
Когда хэши совпадают, происходит авторизация с помощью скрипта. При отсутствии совпадений, возвращается ошибка.
Давайте подробно остановимся на том, что значит «авторизироваться». В нашем скрипте информация о PHP-авторизации хранится в cookie и сессии. В сессию записывается id пользователя:
$id = $_SESSION['id'];
Кроме того, создаются 2 cookie: login и password. Продолжительность жизни — 50 тыс. секунд. В первый пишется логин, во 2-й — хэш пароля.
lastAct($id);
В данной строке выполняется функция, которая устанавливает время последней активности юзера. Код:
function lastAct($id) { $tm = time(); mysql_query("UPDATE users SET online='$tm', last_act='$tm' WHERE id='$id'"); }
С помощью функции перезаписываются поля online и last_act в базе данных. Здесь, кстати, важно убедиться, что эти поля существуют (оба имеют тип int).
Теперь посмотрим на алгоритм работы функции
Идём дальше. Следующая функция нужна для проверки, авторизирован ли юзер на сайте —
function login () { ini_set ("session.use_trans_sid", true); session_start(); if (isset($_SESSION['id']))//если сесcия есть { if(isset($_COOKIE['login']) && isset($_COOKIE['password'])) //если cookie есть, обновляется время их жизни и возвращается true { SetCookie("login", "", time() - 1, '/'); SetCookie("password","", time() - 1, '/'); setcookie ("login", $_COOKIE['login'], time() + 50000, '/'); setcookie ("password", $_COOKIE['password'], time() + 50000, '/'); $id = $_SESSION['id']; lastAct($id); return true; } else //иначе добавляются cookie с логином и паролем, чтобы после перезапуска браузера сессия не слетала { $rez = mysql_query("SELECT * FROM users WHERE id='{$_SESSION['id']}'"); //запрашивается строка с искомым id if (mysql_num_rows($rez) == 1) //если получена одна строка { $row = mysql_fetch_assoc($rez); //она записывается в ассоциативный массив setcookie ("login", $row['login'], time()+50000, '/'); setcookie ("password", md5($row['login'].$row['password']), time() + 50000, '/'); $id = $_SESSION['id']; lastAct($id); return true; } else return false; } } else //если сессии нет, проверяется существование cookie. Если они существуют, проверяется их валидность по базе данных { if(isset($_COOKIE['login']) && isset($_COOKIE['password'])) //если куки существуют { $rez = mysql_query("SELECT * FROM users WHERE login='{$_COOKIE['login']}'"); //запрашивается строка с искомым логином и паролем @$row = mysql_fetch_assoc($rez); if(@mysql_num_rows($rez) == 1 && md5($row['login'].$row['password']) == $_COOKIE['password']) //если логин и пароль нашлись в базе данных { $_SESSION['id'] = $row['id']; //записываем в сесиию id $id = $_SESSION['id']; lastAct($id); return true; } else //если данные из cookie не подошли, эти куки удаляются { SetCookie("login", "", time() - 360000, '/'); SetCookie("password", "", time() - 360000, '/'); return false; } } else //если куки не существуют { return false; } } }
Возникает вопрос, почему для авторизации используем и сессию, и cookie? Всё дело в том, что при закрытии браузера сессия «умирает», а пользователь автоматически разлогинивается. А вот cookie хранятся определённое время, задаваемое нами (50 тыс. секунд).
Дальше у нас функция
Наша функция вернёт true, когда юзер авторизирован, а в обратном случае — false. При этом в процессе работы обновится время жизни cookie или они будут созданы, если вообще не существуют.
Очередной алгоритм работы:
Когда есть сессия и cookie, обновляется время жизни cookie. Чтобы это реализовать, они удаляются, время смерти устанавливается на одну секунду раньше текущего времени, потом устанавливаете заново. Также нужно учесть, что функция
Когда сессия есть, а cookie почему то нет, то по id юзера мы получаем из базы данных логин и хэш пароля, потом пишем их в cookie. Возвращается true.
Когда сессии нет, проверяем, существуют ли cookie. Традиционный пример — PHP-авторизация после перезапуска браузера, когда сессия слетела, но cookie всё ещё живы. Становится сложнее, ведь нужно проверить, а совпадает ли пара пароль-логин с какой-нибудь строкой из базы данных. Ведь пользователь легко мог сменить cookie в настройках для сайта. Если пара нашлась, создаётся переменная сессии, возвращается true. Если пара не нашлась, возвращается false.
Если у нас самый печальный вариант — ни сессии, ни cookie не оказалось, возвращается false.
Сейчас глянем на функцию
Когда наш юзер обыкновенный пользователь, значению в столбце присваивается 0, иначе — 1. Соответственно, в первом случае вернётся false, во втором — true.
function is_admin($id) { @$rez = mysql_query("SELECT prava FROM users WHERE id='$id'"); if (mysql_num_rows($rez) == 1) { $prava = mysql_result($rez, 0); if ($prava == 1) return true; else return false; } else return false; }
Последняя функция — это
function out () { session_start(); $id = $_SESSION['id']; mysql_query("UPDATE users SET online=0 WHERE id='$id'"); //обнуляется поле online, говорящее, что пользователь вышел с сайта (пригодится в будущем) unset($_SESSION['id']); //удалятся переменная сессии SetCookie("login", ""); //удаляются cookie с логином SetCookie("password", ""); //удаляются cookie с паролем header('Location: http://'.$_SERVER['HTTP_HOST'].'/'); //перенаправление на главную страницу сайта }
Код всех наших функций нужно поместить в файл lib/module_global.php, подключаемый в начале работы контроллера.
Итак, мы написали функциональную, но простую PHP-регистрацию/аутентификацию/авторизацию для сайта. Также заложили фундамент для дальнейших возможностей по администрированию и не только. Такая PHP-авторизация не слетит после перезапуска браузера, т. к. мы используем cookie. Предусмотрен и выход с сайта.
Источник: https://true-coder.ru/php/pishem-avtorizaciyu-na-php.html.