Как правильно сделать аутентификацию на php?

Здравствуйте.

Собственно, вопрос простой: нужно сделать аутентификацию на php. Есть таблица в БД с логином/паролем, есть страница логина, есть страница, куда нужно пускать только залогиненных пользователей. Всё максимально просто, логин только на текущую сессию, кнопка «Запомнить меня» не нужна.

Мои познания в этом заканчиваются на книге «PHP для начинающих» 2005-го года, где это сделано так: если логин и пароль правильные, то создаётся сессия с единственной переменной в ней user_id, в которой хранится айди пользователя в базе или 0, если пользователь не залогинен. Она же и используется для проверки доступа. Но у меня есть подозрение, что это не совсем правильно и не очень безопасно.

Погуглив, я посмотрел исходники Yii, Симфони и PHPixie, чтобы узнать, как аутентификация сделана у умных людей, но для меня этот код слишком сложен для понимания. Слишком много токенов, провайдеров, доменов и прочего.
  • Вопрос задан
  • 1733 просмотра
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Погуглив, я посмотрел исходники Yii, Симфони и PHPixie, чтобы узнать, как аутентификация сделана у умных людей


Не забывайте, что в фреймворках это все сделано с одним расчетом - покрыть 95% возможных юзкейсов. А в связи с этим реализация чуточку сложнее. Так же не стоит забывать, что все это "должно" работать на php5.4+, а, например password api появился только в 5.5, а хэширование пароля это целая наука.

Давайте разложим задачу на под задачи:

Нам нужно проверить введенные пользователем данных. Это может быть пара идентификатор + какой-то секретный ключь (email + пароль если проще), а может это просто секретный ключ (токен), или JWT токен... словом вариантов тут много, но нам пока нужна пара старых добрых email + пароль.

Для этого в PHP есть весьма простая в использовании апишка для работы с паролями: password api. Используйте только ее (или что-то что ее под копотом использует) ибо это самый безопасный и надежный способ работы с паролями в PHP. Обязательно прочитайте этот раздел документации.

В очень простом случае (коих большинство) вам при регистрации нужно просто загнать строчку в password_hash и получить на выход новую строчку, которая пишется в базу. При логине мы забираем пользователя с указанным email и проверяем введенный пароль через функцию password_verify.

После того как мы убедились что пользователь не выдает себя за другого, мы можем создать сессию. В самом простом случае мы просто создаем сессию с ID юзера и... собственно все. идентификатор сессии будет записан в http-only куку и все здорово. Правда при работе с сессиями в PHP нужно помнить про CSRF атаки, от которых нужно защищаться (что умеют практически все фреймворки из коробки).

Далее механизмы именно авторизации, то есть разграничения прав, можно упростить от банальной иерархии ролей, до более сложной системы воутеров (шаблон проектирования цепочка обязанностей). Все зависит от потребностей.

p.s. поскольку этот вопрос весьма щепетильный, и ля того что бы сделать все это "безопасным" нужно порядком опыта, я рекомендую вам разобраться с фреймворками или готовыми популярными библиотеками.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
index0h
@index0h
PHP, Golang. https://github.com/index0h
Попробуйте использовать пример из Symfony, но с включенным xdebug. Пройдите процесс аутинтефикации от начала запроса и до отдачи ответа. На самом деле xdebug стоит использовать в принципе для ситуаций, когда вы не знаете, что в коде происходит))
Ответ написан
Комментировать
edli007
@edli007
full stack, team lead
PHP для начинающих» 2005-го года, где это сделано так: если логин и пароль правильные, то создаётся сессия с единственной переменной в ней user_id, в которой хранится айди пользователя в базе или 0, если пользователь не залогинен. Она же и используется для проверки доступа. Но у меня есть подозрение, что это не совсем правильно и не очень безопасно.


Кажется эта книга напечатана с еще более старой.
1. в базе - ид, логин и хешированный пароль.
2. в сессии какой нибудь uid. Если uid в сессии нет - пользователь гость.
как это между собой взаимодействует - на ваше усмотрение.
Ответ написан
Комментировать
kursorik2
@kursorik2
Junior-Developer
Думаю что Сергей Протько всё достаточно разжевал, но приведу ,безопасный и простой код, чтобы было понятнее:
// Готовим запрос к базе данных ...
$pdo->$main->pdo_prepare("SELECT `*` FROM TABLE `xxx` WHERE login=`?` AND password= `?`");
// Готовим плейсхолдеры и формируем пейлоад.
$pdo->$main->pdo_append(array(html_real_escape($_REQUEST["login"]),html_real_escape($_REQUEST["password"])));
// Выполняем запрос в базу ...
$pdo->$main->pdo_execute();
// Читаем запрос из базы в виде ассоциативного массива...
$pdo->$main->fetch_row();
if($row["login"] == $_REQUEST["login"]) {
echo "Пользователь прошёл проверку, доступ разрешён.";
} esle {
echo " Пользователь не прошёл проверку. ";
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы