PHP. Урок 16. Проверка авторизации. Функция check().
Проверка авторизации. Функция check()
Предыдущие уроки:
Программируем на PHP - Введение
PHP - Запросы от браузера к серверу
PHP - Как работает сервер
PHP - Урок 4. PHP - интерпретатор
PHP - Урок 5. Переменные сервера и глобальные переменные
PHP - Урок 6. Конструкции print и echo. Кавычки одинарные и двойные и конкатенация строк
PHP - Урок 7. Переменные, константы и условия
PHP - Урок 8. Точка входа в приложение. Настройка mod_rewrite и файл .htaccess
PHP - Урок 9. Массивы и switch. Кодим основной каркас
PHP - Урок 10. COOKIE
PHP - Урок 11. Функции. Добавляем ядро системы core.php
PHP - Урок 12. Обзор модели MVC. Добавляем шаблоны страниц в наше приложение
PHP - Урок 13. Введение в базы данных и SQL. СУБД MySQL. Подключаемся к БД из нашего приложения
PHP - Урок 14. Регистрация пользователей на сайте
PHP Урок 15. Авторизация пользователей
Теория
Как мы знаем в соцсетях, после того как мы авторизировались, нам уже не требуется каждый раз вводить свой логин и пароль, когда мы используем тот же браузер с которого авторизировались. При этом я уже упоминал, что на самом сервере, запросы HTTP от клиентов, никак не запоминаются (логи не считаются), а связь между ними реализуется программно на основе полученных в запросе идентификационных данных. Таким образом, получается, что существует некая скрытая авторизация. А идентификационные данные передает сам браузер в запросе, но скрывает эту процедуру от пользователя. Подобная технология основана на куках. О которых я ранее заблаговременно рассказал. Поэтому сегодня вспомним только основные аспекты. Итак, в предыдущем уроке, мы создали страницу авторизации (login). Когда мы авторизируемся, скрипт проверяет, есть ли такой логин ипароль в базе данных, и если есть, то из базы данных получаем id этого пользователя генерируется hash, который сохраняется в запись к пользователю с этим id-ом (как альтернатива парою). А затем этот id и hash мы сохраняем в cookie пользователя. Таким образом теперь при каждом запросе к нашему сайту браузер клиента будет в заголовках эти куки передавать. А мы в нашем скрипте при получении таких запросов сможем их считывать через суперглобальный массив $_COOKIE (аналогично данным из $_GET и $_POST). Поэтому логика нашей скрытой авторизации такая же как и при обычной - получаем идентификационные данные и сравниваем их с теми что в базе данных. Разница здесь в нескоьком: 1 - вместо массива $_POST мы поучаем данные из кук $_COOKIE. 2 - Вместо email и password мы сравниваем id и hash (что необходимо для безопасности - что бы хакеры не украли логин и пароль из кук). А дольше происходит все по похожему сценарию как у обычной авторизации. Давайте посмотрим.Практика
Сегодня мы сделаем только 2 вещи:Напишем функцию chech(), которая будет выполнять описанную выше проверку.
Добавим вызов в index.php.
Функция check
// Проверка авторизации
function check($pdo, $cookie_id, $cookie_hash){
if(empty($cookie_id) || empty($cookie_hash)){
return 0;
} else {
$sql = "SELECT hash FROM ts_users WHERE id='$cookie_id'";
if(!$stmt = $pdo->query($sql)){
return 0;
} else {
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(!$row){
return 0;
} else {
$db_hash = $row['hash'];
if($cookie_hash == $db_hash){
return $cookie_id;
}
return 0;
}
}
}
}
Добавляем вызов функции check в index.php
Этот код мы добавим не в switch как часто делаем, а перед ним.
$cookie_id = $_COOKIE['id'];
$cookie_hash = $_COOKIE['hash'];
$this_id = check($pdo, $cookie_id, $cookie_hash);
Дело в том, что паша переменная $this_id будет использоваться везде, где понадобится, а не только на одной конкретной страницы сайта. Таким образом она должна быть инициальзирована в любом случае.
Наша переменная $this_id - это некий фаг. По нему в разных местах нашего приложения (в частности в шаблонах) будем определять ID пользователя, который на данный момент авторизирован.
Если $this_id возвращает вместо id пользователя 0 - значит куки не совпадают с учетными данными пользователя из базы данных, и пользователь не авторизирован.
(Кстати на время отладки у нас срок хранения кук в браузере установлен 1 час (3 параметр setcooie). Поэтому через час после авторизации они будут удаляться и функция возвратит 0 вместо id (что соответствует false).
Чтобы проверить работает и проверка после switch-a добавьте рспечатку значения этой переменной:
print '<br>'.$this_id;
Просто у нас раньше есть отправка заголовков, а вывод нельзя делать до отправки заголовков, как мы помним иначе заголовки не отправятся.
Теперь если мы пройдем по ссылке thesite.loc/login
и войдем в систему под ранее зарегестрированным логином, то поучим в переменной $this_id - id авторизированного пользователя.
Таким образом мы сможем по этой переменной как проверять авторизирован и пользователь вообще (на истинность) так и поучать id пользователя.