Описание веток
sozdanie-formy-registratsii-i-avtorizatsii-v-php – В этой ветке находятся исходники функционала, который был реализован в статье Создание формы регистрации и авторизации
Что делать дальше?
И вот мы подбираемся к самому интересному: а где хранить пароли и в каком виде? Давайте сначала подумаем, где их хранить.
Что такое сессии?
Попробую рассказать в паре абзацев.
Сессии – это механизм, который позволяет однозначно идентифицировать пользователя.
По-человечески это значит, что для каждого посетителя сайта можно создать уникальное “хранилище”, к которому будет доступ только у этого самого посетителя.
Хранилище это хранится в файле на сервере.
На самом деле сессии хранятся не обязательно в файлах. Например, cms Modx хранит их базе данных.
Но сейчас нам это не важно, главное, что сессии предоставляют удобный способ работать с данными, уникальными для пользователя.
Для нас сессия выглядит как обычный ассоциативный массив под названием $_SESSION, в разные поля которого можно записать хоть число, хоть строку, хоть сериализованный объект.
Что такое хеширование
Отпечаток (хэш) — это результат работы функции хэширования, которая вернёт для любого значения строку фиксированной длины.Используя специальный математический алгоритм, такая функция умеет преобразовывать любую переданную информацию к строке фиксированной длины (например, 32 или 64 символа).
Причём любому массиву информации, будь это все статьи из Википедии, или одно слово, всегда будет соответствовать уникальный отпечаток. Повторный вызов функции для одного и того же исходника всегда возвращает один и тот же хэш.Обратная операция (получить из отпечатка оригинал) невозможна.
Возьмём простой пример. У нас есть информация, для которой мы хотим получить отпечаток. Пусть такой информацией будет следующая строка:
«Я знаю только то, что ничего не знаю, но другие не знают и этого»
Результат обработки этой строки хэширующей функцией SHA-1 будет таким:6b3cb0df50fe814dee886b4e1c747dda6ce88b37
Хэширующие функции часто используются для контроля целостности информации при передачи по сети. Например, чтобы убедиться в том, что загруженный файл не был повреждён, достаточно получить его хэш и сравнить данный хэш с опубликованным на сайте. Если в файле поменялся хоть один байт, то эти отпечатки будут совершенно разными.Нам же функции хэширования помогут для сравнения паролей.
The Logout script
Finally, Let’s create a logout.php file with the following code in it.
Cookies
Cookies (в дальнейшем просто «куки») — небольшие фрагменты данных, которые веб-сервер отправляет браузеру.Браузер сохраняет их у себя, а при следующем посещении веб-страницы отправляет обратно. Благодаря этому, веб-сервер сможет узнать своего «старого» посетителя, идентифицировать его.
Step 1: creating a login form in html
Below is the Login Form in HTML. Paste it in a file named login.php
Step 1: creating registration form in html
We will create a PHP file named register.php with the following code in it. This is a simple HTML form with some basic validation. If you are not familiar with HTML then you can get it from many online sites who give ready-made html5 login form templates.
Аутентификация
Представим интернет-магазин. Все его страницы можно разделить на две половины: публичные и приватные.К публичным относятся страницы каталога, информации о товаре, условия доставки и так далее. К приватным — корзина покупок, история заказов.Совершенно очевидно, что корзина покупок у каждого покупателя должна быть своя, а иметь к ней доступ должен только сам владелец и никто больше.
Процедура проверки возможности доступа пользователя к определенной части сайта и называется аутентификацией.Весь процесс аутентификации всегда состоит из нескольких шагов:
Выбираем правильное хэширование
Идею хранения паролей нашли, то есть хранения не паролей, а их хэшей. А вот какой алгоритм хэширования выбрать?
Давайте посмотрим на то, что пробовали выше – простая функция md5. Алгоритма его расшифровки нет, но тем не менее md5 не рекомендуется для использования. Почему?
Помимо сложности самого алгоритма, есть и другой момент. Да, расшифровать пароль по хэшу нельзя, но его можно подобрать. Простым брутфорсом.
К тому же существуют многочисленные базы паролей md5, где всевозможные варианты хранятся тупо списком.
И подбор вашего пароля по известному хэшу займет столько времени, сколько понадобится для выполнения sql-запроса
select password from passwords where hash='e10adc3949ba59abbe56e057f20f883e';
Конечно, вы сами не будете использовать пароль 123456, но как насчет ваших пользователей? Да, 123456 можно подобрать и руками, но в таком случае никакие алгоритмы не помогут.
Наша же задача максимально позаботиться о юзерах, которые выбирают пароли сложнее qwerty. Думаем дальше, гуглим.
Помимо md5 есть множество алгоритмов хэширования, sha256, sha512 и еще целая толпа. Их сложность выше, но это не отменяет опять-таки существования таблиц с готовыми паролями.
Нужно что-то хитрее.
Выход с сайта
Если на сайте есть вход, то должен быть и выход. Таким выходом будет специальный сценарий, который очистит сессию и переадресует на главную страницу.Чтобы очистить сессию, достаточно очистить массив $_SESSION:$_SESSION = []
Ещё немного терминологии
Следует различать два термина: аутентификация и авторизация.
Заглушка для авторизации
Функции, связанные с авторизацией, будут лежать в отдельном файле и своем пространстве имен. Создадим файл auth.php в api/v1/common – там, где уже лежит helpers.php.
Если вы разбирали уроки админки, особенно третий, про серверную часть, то эти пути вам будут знакомы. Если у вас свой проект, то кладите auth.php куда удобно.
Главное, потом правильно указать пути.
Содержимое auth.php
Как прочитать куки
В PHP максимально упрощён процесс чтения информации из кукисов. Все переданные сервером куки становятся автоматически доступны в специальном глобальном массиве $_COOKIEТак, чтобы получить содержимое куки с именем «visit_count», достаточно обратиться к одноимённому элементу массива $_COOKIE, например вот так:
Обратите внимание: установив в сценарии куку через setcookie, прочитать её можно будет только при следующем посещении страницы.
Как установить куки: функция setcookie
Являясь серверным языком программирования, PHP может управлять заголовками, которые отправляет сервер, а значит может устанавливать и читать куки.Чтобы добавить новую куку, необходимо вначале определиться со следующими критериями:
- Название этой куки (может состоять только из символов латинского алфавита и цифр);
- Значение, которое предполагается хранить;
- Срок жизни куки — это обязательное условие.
За установку куки в PHP отвечает функция setcookie, ей нужно передать как минимум три параметра, описанных выше. Пример:
Обратите внимание, что срок жизни указывается в относительной величине. В этом примере кука будет существовать ровно 30 дней с момента установки.
Как устроены сессии
- PHP генерирует уникальный идентификатор браузера.
- Идентификатор сохраняется в специальную куку и передаётся с каждым запросом.
- Все данные, которые записываются в сессию, PHP автоматически сохраняет в специальном файле на сервере.
Благодаря существованию сессий в PHP, мы можем сохранять любые данные так же просто, как присваивать их переменным. Но, в отличие от переменных, эти данные будут сохраняться для пользователя между запросами в пределах сеанса.
Перепишем сценарий для подсчета посещений, но теперь используем сессии:
Подключение к базы данных
В корневую папку сайта, создаем файл с названием “dbconnect.php”. В этом файле, добавляем следующий код:
<?php
// Указываем кодировку
header('Content-Type: text/html; charset=utf-8');
$server = "localhost"; /* имя хоста (уточняется у провайдера), если работаем на локальном сервере, то указываем localhost */
$username = "имя_пользователя_бд"; /* Имя пользователя БД */
$password = "пароль_пользователя_бд"; /* Пароль пользователя, если у пользователя нет пароля то, оставляем пустым */
$database = "имя_базы_данных"; /* Имя базы данных, которую создали */
// Подключение к базе данный через MySQLi
$mysqli = new mysqli($server, $username, $password, $database);
// Проверяем, успешность соединения.
if ($mysqli->connect_errno) {
die("<p><strong>Ошибка подключения к БД</strong></p><p><strong>Код ошибки: </strong> ". $mysqli->connect_errno ." </p><p><strong>Описание ошибки:</strong> ".$mysqli->connect_error."</p>");
}
// Устанавливаем кодировку подключения
$mysqli->set_charset('utf8');
//Для удобства, добавим здесь переменную, которая будет содержать название нашего сайта
$address_site = "http://testsite.local";
?>
Пример
Задача очень проста: сохранять и показывать посетителю страницы, сколько раз он посетил наш сайт. Для этого будем сохранять количество посещений в отдельной куке, увеличивая значения на единицу при каждой загрузке страницы.
Проверяем работоспособность vue
Вроде бы, чего там может сломаться? Нам же практически не пришлось лезть в код vue, за исключением добавления кнопки Выйти в шапке админки.
Но попробуем пересобрать админку, чтобы убедиться, что все хорошо. Сначала в production режиме
npm run build
Реализация регистрации пользователя
Вернёмся к форме регистрации.Выше говорилось, что вместо пароля лучше хранить его отпечаток. Для получения отпечатка существуют множество хэшируюших функций. К счастью, нам не надо разбираться в их многообразии, потому что в PHP есть стандартная функция, которая делает ровно то, что нужно.Вот пример как из пароля получить отпечаток, пригодный для хранения в базе:
$passwordHash = password_hash('iloveponies', PASSWORD_DEFAULT);
Вызов этой функции вернёт следующую строку: $2y$10$a1pgDBerBsqD24D7qOAsl.QFTvwxQQGe4r1oWhD7f9yEnDvx4i7tWИменно это значение и следует хранить в БД, вместо пароля.
Регистрация на сайте
Перед тем, как мы начнем добавлять аутентификацию на своем сайте, придётся добавить форму для регистрации нового аккаунта.Аккаунт — это учётная запись пользователя.Чтобы завести аккаунт, требуется пройти регистрацию — это заполнение специальной формы, где пользователь указывает свою почту, пароль, и, возможно, дополнительную информацию.
Собираем всё вместе
Теперь, научившись устанавливать и читать куки, напишем полноценный сценарий, который будет считать и выводить количество посещений страницы пользователем:
Хранение паролей
Пароль пользователя — это секретный набор символов, который используется в дальнейшем в ходе аутентификации. Зная пароль пользователя, злоумышленник может войти на сайт под его именем. По этой причине пароль нельзя хранить в базе в открытом виде. Ведь если информацию из БД сайта украдут, то
данные всех пользователей станут скомпрометированными.Вместо самого пароля, в базе будут храниться их отпечатки — хэши.
Шаг 8
И последний штрих. Мы можем ограничивать доступ не только к странице админки, но и к любой другой. Для этого достаточно открыть сессию и проверить наличие метки в ней. Чтобы не копировать на каждую новую страницу эти блоки кода — мы их можем вынести в отдельный файл (auth.php) и затем просто подключать этот файл на страницах, к которым нужно ограничить доступ по паролю. Содержимое файла auth.php будет таким:
Вместо заключения
Проблемы с dev режимом во vue – это неприятный момент. Мы хотим и апишечку подергать, и все удобства vue-cli использовать. И на елку влезть, и ничего не ободрать.
Возможно, есть более изящный способ обойти эти проблемы в dev режиме, но я их пока не нашел. Поэтому приходится подпирать код лишними условиями.
Заключение
На этом наш урок завершен, мы выполнили поставленную в уроке задачу — написали свою простенькую систему авторизации. Конечно, как говорилось выше, для серьезных проектов такая система авторизации мало подходит, поскольку пользователей у нас может быть больше одного и хранить их нужно в БД.
Да и шифрование пароля функцией md5() часто также бывает неэффективно, поскольку существуют сервисы с базами хешей… но для нас главное было понять принцип построения системы авторизации, а строится она именно по такому принципу. Итак, урок окончен. До новых встреч.