Безопасный метод авторизации на PHP
Давайте посмотрим вокруг: форумы, интернет магазины, гостевые книги и т.д. используют регистрацию и последующую авторизацию пользователей. Можно даже сказать, что это почти необходимая функция каждого сайта (только если это не домашняя страничка Васи Пупкина или не визитная карточка, какой-нибудь небольшой компании). Сегодня я хочу поделиться со всеми новичками информацией, о том, как лучше это все реализовать.
Модель авторизации:
Клиент
Сервер MySQL
При регистрации в базу данных записывается логин пользователя и пароль(в двойном md5 шифровании)
При авторизация, сравниваеться логин и пароль, если они верны, то генерируеться случайная строка, которая хешируеться и добавляеться в БД в строку user_hash. Также записываеться IP адрес пользователя(но это у нас будет опциональным, так как кто-то сидит через Proxy, а у кого-то IP динамический. тут уже пользователь сам будет выбирать безопасность или удобство). В куки пользователя мы записываем его уникальный индетификатор и сгенерированный hash.
Почему надо хранить в куках хеш случайно сгенерированной строки, а не хеш пароля?
1. Из-за невнимательности программиста, во всей системе могут быть дырки, воспользовавшийсь этими дырками, злоумышленик может вытащить хеш пароля из БД и подставить его в свои куки, тем самым получить доступ к закрытым данным. В нашем же случае, двойной хеш пароля не чем не сможет помочь хакеру, так как расшифровать он его не сможет(теоретически это возможно, но на это он потратит не один месяц, а может быть и год) а воспользоваться этим хешем ему негде, ведь у нас при авторизации свой уникальный хеш прикрепленный к IP пользователя.
2. Если злоумышленик вытащит трояном у пользователя уникальный хеш, воспользовать им он также не сможет(разве если только, пользователь решил принебречь своей безопастностью и выключил привязку к IP при авторизации).
Реализация
Структура таблицы `users` в базе данных ‘testtable’
register.php
login.php
check.php
logout.php
Для защиты формы логина от перебора, можно использовать капчу или временную задержку на повторную авторизацию.
Автор: http://jiexaspb.habrahabr.ru/. Адаптация под PHP 5.5 и MySQL 5.7 KDG.
Куки с флагом HttpOnly не видны браузерному javascript-коду, а отправляются только на сервер. На практике у вас никогда нет необходимости получать их содержимое в javascript. А вот злоумышленнику, нашедшему XSS — а XSS так или иначе когда-нибудь где-нибудь найдется — отсутствие HttpOnly на авторизационных куках доставит много радости.
Будни программиста
Пишем свою авторизацию на PHP и MySQL
Ну что же, сегодня я вам расскажу о безопасной авторизации на PHP и Cookie. Ну о том что она абсолютна безопасна я не говорю, ибо взломать можно все, но для маленького сайта она вполне подходит. Так же я предвижу комментарии о том что сессии безопаснее. Не спорю куки уступают сессиям в безопасности но для реализации простенькой авторизации вполне подходят. Подробности ниже.
И так, в базе у нас будет 1 база из 4 полей: users_id, users_login, users_password и users_hash. SQL запрос:
Давайте разберем каждый файл.
conf.php
В константах содержится данные SQL подключения, а именно хост, логин, пароль и имя вашей базы. Тут же мы подключаемся к базе, устанавливаем кодировку в которой будут передаваться данные в бд и выбираем бд с которой будем работать. Так же тут содержится массив ошибок которые могут возникнуть при авторизации.
# массив ошибок
$error [ 0 ] = ‘Я вас не знаю’ ;
$error [ 1 ] = ‘Включи куки’ ;
$error [ 2 ] = ‘Тебе сюда нельзя’ ;
?>
register.php
Файл регистрации, тут содержится простейшая форма и ее обработчик. Исходный код прокомментирован, но общий процесс я коротко опишу. Вначале проверяем наш логин, он может содержать только английские буквы и цифры. Далее мы проверяем длину логина, от 3 до 30 символов. Проверяем свободен ли логин. При успешных проверках добавляем нового пользователя в базу. Из введенного пароля мы вырезаем пробелы на случай если пользователь хранит свои пароли в каком ни будь текстовом файле (в windows текстовые редакторы любят «хватать» пробелы в начале или конце выделяемого текста). Шифруем пароль в двойном MD5 и добавляем в базу данные о новом пользователе. Перебрасываем пользователя на login.php.
# Подключаем конфиг
include ‘conf.php’ ;
login.php
Опять кратко расскажу о действиях совершаемых в данном скрипте. В самом начале у нас висит функция для генерации случайной строки, она служит для хеша пользователя (чуть позже более подробно). Далее мы проверяем наличие куков с ошибками (они ставятся в check.php). Подключаем файл конфигурации и проверяем пользователя. Вытаскиваем из бд логин и пароль, сравниваем с введенными и генерируем хеш. Записываем в бд новый хеш пользователя и ставим куки. В куках находится id и хеш пользователя. Пересылаем пользователя на check.php.
# Подключаем конфиг
include ‘conf.php’ ;
# Переадресовываем браузер на страницу проверки нашего скрипта
header ( «Location: check.php» ) ; exit ( ) ;
>
else
<
print «Вы ввели неправильный логин/пароль
» ;
>
>
?>
check.php
И последний файл, который содержит проверку авторизации пользователя. В начале подключаем конфиг и если существуют куки начинаем проверку, если их нет, то ставим куки с номером ошибки и отсылаем на login.php. И так проверка. Вытаскиваем из бд id и хеш. Если они не проходят проверку на соответствие с теми куками которые стоят у посетителя, то удаляем существующие куки посетителя и ставим куки с номером ошибки, пересылаем на login.php. Если же все нормально то пользователь увидит страницу.
# подключаем конфиг
include ‘conf.php’ ;
Создание форм регистрации и авторизации на PHP
Система регистрации и авторизации необходима для любого сайта, который хранит информацию о своих пользователях. Такие системы используются на сайтах самой разнообразной тематики – от образовательных платформ, которые хранят сведения о прохождении обучающих курсов и оценках, до онлайн-магазинов, которые сохраняют историю покупок и адреса пользователей. В этом руководстве мы научим вас создавать формы регистрации и авторизации с нуля.
Разработка форм регистрации и авторизации
Мы рассмотрим процесс создания простых форм для регистрации и авторизации пользователей. Регистрационная форма будет содержать поля для ввода имени, пароля и адреса электронной почты. Имя пользователя и адрес электронной почты при этом должны быть уникальными для каждого конкретного пользователя. В случае попытки регистрации второй учетной записи с таким же именем пользователя (или электронной почтой) будет выводиться сообщение об ошибке с пояснением о том, что такие данные уже используются в системе.
Код регистрационной формы
Ниже приведен HTML-код необходимый для создания формы регистрации. Сохраните его вфайле register.php.
Несмотря на простоту данной формы, для проведения простейшей валидации данных в ней используется HTML5. К примеру, использование type=»email» обеспечит уведомление пользователя о том, что он неправильно ввел адрес электронной почты. Кроме того, применение pattern позволит провести проверку имени пользователя – логин может состоять только из латинских букв и цифр.
Наиболее продвинутый способ валидации данных подразумевает использование jQuery – в этом случае разработчик получает полный контроль над показом, расположением и внешним видом сообщений об ошибках ввода. Подробнее о валидации на стороне клиента с использованием jQuery рассказывается в этой статье.
Исходный код страницы авторизации
CSS-стили для оформления форм
Для улучшения внешнего вида форм примените к ним следующие CSS-стили:
В коде, приведенном выше, предусмотрено оформление заголовков и сообщений об ошибках валидации. Фрагменты HTML и CSS кода, рассмотренные выше, могут использоваться в качестве основы, поскольку ваш собственный проект может нуждаться в другом стиле оформления, а также в дополнительных полях ввода.
Создание таблицы с учетными данными и подключение к базе данных
Следующий шаг – создание таблицы базы данных, содержащей учетные данные пользователей. В нашем случае таблица состоит всего из четырех столбцов:
Для быстрого создания таблицы базы данных можно использовать следующий SQL-запрос:
Теперь создайте файл config.php и сохраните в нем приведенный далее код для подключения к базе данных:
В приведенном выше коде замените название базы данных на то, которое вы используете для своего собственного сайта.
Исходный код для регистрации пользователей
Теперь пришла очередь написать код для регистрации пользователей. Главная функция этого кода – проверить, не зарегистрирован ли уже аналогичный адрес электронной почты в базе данных. Если нет, новое имя пользователя вместе с адресом его электронной почты и паролем передаются для сохранения в базе данных.
Сохраните приведенный далее код в начале файла registration.php :
На первом этапе выполнения кода включается config.php, начинается сессия. Так мы получаем возможность сохранить любую информацию для дальнейшего использования на всех страницах сайта.
После этого мы проверяем, существует ли предоставленный пользователем адрес электронной почты в базе данных. Если это так, пользователь получит соответствующее сообщение. Если же такого email-адреса в базе данных, используемой сайтом, нет, вся введенная информация сохраняется в базе данных и пользователь видит сообщение об успешной регистрации.
Функция авторизации
На предыдущем этапе мы уже сохранили код для формы авторизации пользователей в системе. На этом этапе мы будем проверять, соответствуют ли введенные пользователем данные учетной записи, сохраненной в базе.
Приведенный далее код должен располагаться в начале файла login.php:
Важно отметить, что мы не проверяем правильность имени и пароля одновременно. Поскольку пароль сохранен в хэшированном виде, сначала необходимо запросить хэш с помощью предоставленного имени пользователя. Когда мы получим хэш, можно будет проверить предоставленный пользователем пароль на соответствие хэшированному – с помощью функции password_verify().
Ограничение доступа к страницам
На большинстве сайтов, запрашивающих учетные данные посетителей, есть страницы, на которых зарегистрированные пользователи хранят свою личную информацию. Для защиты подобных страниц от несанкционированного доступа можно использовать переменные сессии. Если переменная сессии не создана, пользователь перенаправляется на страницу авторизации. Если переменная сессии создана, пользователь видит содержимое страницы:
Все, что нужно сделать для ограничения или предоставления доступа – это использовать в начале приведенного выше скрипта строку session_start().
Типичные ошибки и способы их решения
При использовании скрипта для ограничения доступа неавторизованных пользователей обычно возникают три типа ошибок.
Некорректное имя переменной
«Заголовки уже отправлены»
Переменные сессии не сохраняются при переходах между страницами
Форма авторизации на php
Продолжаем изучать язык PHP на практике. Тема нашего сегодняшнего урока — «Простая форма авторизации на PHP». Я предлагаю вам подробное описание создания формы авторизации, регистрации и обработчиков файлов с пошаговой инструкцией.
Перед тем, как приступить к работе, мы должны продумать логику построения и работы нашей формы, чтобы потом воплотить её в жизнь средствами языка программирования, в нашем случае — средствами php.
Техническое задание
Итак, для этого нам нужна форма заполнения данных для входа в систему, на которой мы заполняем поля «логин», «пароль»и нажимаем кнопку «Войти», при нажатии которой подключается обработчик, который проверяет эти поля и если они совпадают с существующими в базе (то бишь осуществляется проверка, зарегистрирован ли такой зарегистрирован пользователь в системе), то нам показывается сообщение «Бла-бла-бла, вы зашли на сайт, поздравляем!», форма входа пропадает, а вместо неё появляется кнопка «Закрыть».
Также на форме входа есть ссылка «Регистрация» для тех пользователей, которые ещё не зарегистрировались, но очень хотят это сделать. При клике на эту ссылку мы попадаем уже на третий файл, который отвечает именно за регистрацию пользователей. В этом файле нам нужно прописать поля «Логин», «Пароль», «Повторите пароль», «Email» и кнопка «ОК», при нажатии которой подключается четвёртый файл — обработчик, который заносит заполненные поля в специальную таблицу Базы Данных, осуществляя при этом проверку, заполнены ли все поля.
Список файлов:
Форма авторизации
Помещение HTML-формы в PHP-скрипт
Поля формы авторизации создаются средствами языка разметки HTML, но нам необходимо поместить эту форму в PHP-скрипт, чтобы у нас была возможность работать с php-скриптами прямо в этой форме. Для этого форму заключим в php-скрипт, а выведем её на экраны средствами php, например,
Подключение обработчика формы
Для того, чтобы форма начала работать и данные с полей формы сверялись с данными в Базе Данных, которые были введены при регистрации, нам нужно форму авторизации подключить к обработчику, который и будет обрабатывать форму, сверять значения полей, запускать или не запускать пользователей на сайт. Подключается обработчик легко, нужно всего лишь прописать в теге form атрибут action, то бишь ссылку на обработчик (адрес документа или программы, которая будет обрабатывать данную форму), например:
Обработчик формы авторизации
Чтобы наша форма авторизации работала, то есть взаимодействовала с Базой Данных, мы подключили специальный обработчик script1.php. Именно он проверит введены ли данные в поля авторизации — «Логин» и «Пароль», зарегистрирован ли на сайте пользователь с введёнными параметрами (то бишь, есть ли в БД уже такой пользователь), и если есть, авторизовать его на сайте (если совпадают введённые логин и пароль с существующими в БД). Если такого пользователя нет (не совпадают введённые данные логин и пароль), вывести пользователю эту ошибку.
Для начала нам нужно проверить правильность заполнения форм входа пользователя. Проверяем, заполнены ли пользователем все поля, удаляем экранирование символов, удаляем лишние пробелы, преобразуем символы в html-сущности, открываем сессию и перенаправляем пользователя на нужную страницу после выполнения скрипта. Например:
Ну и, конечно же, нам нужно подключиться к базе данных, чтобы наши скрипты проверки пользователя и его авторизации могли работать. Чтобы подключиться к БД, нужно знать адрес сервера MySQL (mysql.moidomen.com), название базы данных (moya_baza), название пользователя базы данных (moi_login) и пароль к базе данных (moi_parol). В скобках и в примере ниже я указала примерные данные, вы же должны при подключении указать СВОИ данные для того, чтобы подключиться к СВОЕЙ базе данных. Пример подключения к БД:
Далее нам нужно извлечь из БД из таблицы с зарегистрированными пользователями на сайте их логины. Если есть зарегистрированный пользователь с таким логином, сверяем пароли введённые при регистрации и авторизации. Если эти пароли совпадают, авторизовываем пользователья на сайте и выводим информацию на экран, что он вошёл. В противном случае пользователя не авторизовываем (он остаётся, как гость) и показываем информацию, что логин или пароль неверны. Не забываем прописывать функцию защиты пароля md5();, которая переводит пароль в хэш в виде 32-символьного шестнадцатеричного числа. Пример ниже:
Полностью файл script1.php выглядит так:
Форма регистрации
На странице с формой авторизации для незарегистрированных пользователей, но желающих это сделать есть ссылка на страницу с регистрацией, которую нам и нужно создать. Форма регистрации аналогична форме авторизации, разница только в количестве полей и обработчике, который будет эту форму обрабатывать. Поэтому в атрибуте тега form — action прописываем ссылку на обработчик script2.php. Форма регистрации registration.php выглядит следующим образом:
Обработчик формы регистрации
Как форма регистрации готова, приступим к созданию обработчика формы регистрации. Он будет очень похож на обработчик формы авторизации. В них используются практически одинаковые функции. Сначала мы передаём в переменные значение заполненных форм в полях регистрации. Проводим проверку, заполнено ли каждое поле и совпадают ли пароли в обоих полях — в поле «Пароль» и «Подтверждение пароля». Пароль переводим в ХЭШ, используя функцию MD5 (); Она переводит введённый пароль, то есть кодирует его в хэш в виде 32-символьного шестнадцатеричного числа. Как и в обработчике авторизации, в обработчике регистрации прописываем функции, которые в заполненных полях редактируют данные — удаляют экранирование символов, удаляют лишние пробелы, преобразуют символы в html-сущности. Например:
Затем подключаемся к базе данных. На примере обработчика авторизации мы уже знаем как это делать:
Теперь нам осталось занести данные, введённые в поля формы регистрации в таблицу зарегистрированных пользователей registr_users, оповестить новоиспечённого пользователя о том, что регистрация прошла успешно выводом информации в браузер и предложить войти на сайт перейдя для этого по ссылке.
В целом весь файл-обработчик формы регистрации script2.php выглядит так:
Пример формы авторизации
Ну вот, в принципе, и всё. Для наглядности примера авторизации можно посмотреть — поклацать здесь. Там всё тоже самое, только я ещё добавила файл css и подключила его.
Система авторизации с помощью cookie на PHP
В прошлом уроке мы изучили механизм взаимодействия с cookie в языке PHP.
Техническое задание
Начнём мы это дело с описания будущей системы. Пусть у нас будут следующие компоненты:
Решение
Продумываем архитектуру
Первое, о чём нам нужно подумать — это то, как будут храниться элементы этой системы, и сколько их вообще будет.
Начнем с простого — для начала у нас должно получиться 3 странички, которые мы описали в ТЗ.
Ещё нам потребуется функционал, который будет проверять, авторизован ли пользователь. Если мы перечитаем ТЗ, то поймём, что он используется в двух местах — и на главной странице и на странице авторизации. Значит, стоит вынести этот механизм в отдельный файл, и использовать его в двух местах сразу.
Пишем код
Все исходники по данному заданию доступны здесь.
База данных
Ну вот, всё продумали, осталось только написать. Предлагаю начать с нашей базы данных. Создадим файл usersDB.php и запишем в него несколько пользователей.
Функции проверки авторизации
Давайте теперь напишем функцию, которая будет проверять, являются ли переданные в неё логин и пароль правильными. Для этого создадим ещё один файл auth.php. В нём нам для получения списка пользователей потребуется подключить файл с базой данных.
В цикле мы пробегаемся по базе данных пользователей и пытаемся найти пользователя с переданными логином и паролем. Если такой пользователь в массиве найден — возвращаем true. Иначе — false.
Давайте теперь ещё напишем функцию, которая будет возвращать логин текущего пользователя. Эта функция будет проверять текущие значения cookie с ключами login и password с помощью уже существующей функции checkAuth. При этом если пользователь найдётся, то она вернёт его login, а иначе — null. Назовём эту нашу новую функцию getUserLogin.
На этом всю логику проверки логина мы описали. Теперь займёмся непосредственно страничками.
Главная страница
Создадим файл index.php. Для простоты примера мы будем использовать только строку с приветствием авторизованного пользователя, либо ссылкой на авторизацию. В этой странице нам потребуется функция проверки авторизации через cookie, поэтому здесь нужно подключить файл auth.php.
Наша главная страничка готова. Можно зайти на неё и убедиться, что мы не авторизованы.
Форма авторизации
Давайте теперь сделаем форму авторизации — создаём файл login.php и для начала набрасываем саму HTML-форму. Шаблон получился следующим.
Давайте теперь добавим логику проверки переданных данных.
Логика простейшая — если был отправлен POST-запрос, проверяем правильные ли логин и пароль были переданы.
Если же авторизация прошла успешно, мы устанавливаем cookie с ключами login и password, в которые помещаем значения из POST-запроса. После этого выполняем редирект на главную страницу.
Редирект делается с помощью заголовка в HTTP-ответе. Этот заголовок называется Location и выглядит следующим образом:
Для формирования заголовков в PHP используется функция header – ознакомиться с ней более детально вы можете здесь.
Теперь можно попробовать нашу страничку в действии. Давайте для начала введём несуществующую пару логина и пароля. Например, 123:123.
Мы увидим соответствующую ошибку.
Теперь давайте зайдем под пользователем user. В нашей БД для него указан пароль 123. Пробуем.
Успех! Нас автоматически перекинуло на главную страницу, где мы видим приветствие для данного пользователя!
Безопасная система авторизации
Хеширование паролей
В более совершенных системах авторизации используют хеш от пароля.
Если по-простому, то это такое вычисленное значение, полученное в результате выполнения над паролем определенных манипуляций. В результате этих действий мы получаем строку, из которой нельзя восстановить исходный пароль.
Авторизационные токены
Помимо хеша пароля в базе данных так же принято хранить так называемые авторизационные токены (AuthToken). Это комбинация символов (желательно подлиннее и с кучей кракозябр), которая генерируется при успешной авторизации пользователя и сохраняется в базе данных. А ещё она и пользователю отправляется.
Заключение
Ах да, чуть не забыл, все исходники к каждому уроку я для вашего удобства буду выкладывать на github – вот тут.










