Практически у каждого сайта есть аутентификация пользователей, которая проходит с помощью передачи логина и пароля пользователя по определённому алгоритму. Алгоритмы везде разные, есть простейшие, без какой либо защиты, а есть очень хорошо защищённые.
В этой статье будет написано каким образом проводить безопасную аутентификацию пользователей на сайте с помощью языка PHP, баз данных и cookie (печенек).
Начнём с описания, на словах, самого алгоритма аутентификации пользователей.
Внимание!!! Данная статья осталась для истории, поэтому не стоит использовать данный алгоритм на своих сайтах.
Как известно куки можно украсть у определённого пользователя, потом подставить их в свой браузер и свободно перемещаться по какому либо сайту от имени того пользователя, у которого были сворованы эти куки. Вот это главная проблема, по этому нужно сделать так, чтобы если эти куки украдут, то они были бы бесполезны в других браузерах и компьютерах, то есть чтобы была привязка к конкретному компьютеру.
И так, вот сам алгоритм:
- Логин и пароль, введённые пользователем, передаются на сервер;
- С помощью специального алгоритма происходит хэширование пароля;
- Хэш переданного пароля сверяется с хэшем пароля в БД;
- Генерируется новый хэш на основе данных браузера и пароля, этот хэш добавляется в запись БД пользователя;
- При следующих переходах пользователя по страничкам сайта будет сверяться логин, хэш пароля и неизвестный никому хэш, который создаётся динамически на сервере и сверяется с хэшом в БД.
То есть неизвестный никому хэш ни как перехватить нельзя, ибо он не передаётся между клиентом и сервером, а также сгенерировать не зная алгоритма.
При краже куки и подставления их в браузер, можно сделать уничтожение этих кук, после того как будет произведена неудачная аутентификация.
Теперь перейдём к реализации данного алгоритма, он будет немного упрощён, чтобы он получился не большим. Если кому-то понравилась идея, то допишите необходимое сами :)
В БД нам понадобится 4 обязательных поля - это идентификатор, логин, пароль (хэш) и неизвестный хэш. Структура:
- CREATE TABLE `users` (
- `id` INT(11) NOT NULL AUTO_INCREMENT,
- `login` VARCHAR(20) NOT NULL,
- `password` VARCHAR(32) NOT NULL,
- `hash` VARCHAR(32) NOT NULL,
- PRIMARY KEY (`id`)
- );
Заметьте, что длина пароля и хэша в БД у нас равна 32, ибо хэш у алгоритма md5 получается именно такой длины.
HTML форма входа:
- <form action="./index.php" method="post">
- <p>Логин:</p>
- <input type="text" name="login" maxlength="15">
- <p>Пароль:</p>
- <input type="password" name="pass" maxlength="20">
- <input type="submit" name="enter" value="Войти"></form>
А вот собственно сам алгоритм аутентификации:
- if(isset($_POST['enter'])){ //если нажали кнопку входа, то идём дальше
- $sql=mysql_query("SELECT `id`,`login`,`password` FROM users where `login`='".$_POST['login']."' LIMIT 1"); //формирование запроса в БД с ведённым логином
- $user_row=mysql_fetch_array($sql);
- unset($sql);
- $check_pass=md5($_POST['pass'].md5($_POST['pass'].$user_row['login']).$user_row['id']); //примерный алгоритм хэширования пароля, можно сделать что нибудь проще или сложнее
- if($check_pass==$user_row['password']){
- setcookie('login',$user_row['login']); //прописываем в куки логин
- setcookie('hash',$user_row['password']); // прописываем в куки хэш пароля
- }
- $check_pass=md5(($_SERVER['HTTP_ACCEPT_LANGUAGE']).$check_pass.$_SERVER['HTTP_USER_AGENT']); //примерный алгоритм генерации неизвестного хэша
- mysql_query("UPDATE users SET `hash`='".$check_pass."' where `id`='".$user_row['id']."'"); //добавление неизвестного ни кому хэша в запись БД пользователя
- unset($check_pass,$user_row);
- }
- else if(isset($_COOKIE['login']) && isset($_COOKIE['hash'])){ //если есть определённые куки, то начинаем их проверять
- $sql=mysql_query("SELECT `id`,`login`,`password`,`hash` FROM users where `login`='".$_COOKIE['login']."' LIMIT 1"); //опять формуруем запрос для определённого логина в куках
- $user_row=mysql_fetch_array($sql);
- unset($sql);
- $check_user=md5(($_SERVER['HTTP_ACCEPT_LANGUAGE']).$_COOKIE['hash'].$_SERVER['HTTP_USER_AGENT']); //генерация неизвестного ни кому хэша
- if($_COOKIE['hash']!=$user_row['password'] || $check_user!=$user_row['hash']){ //сравнение хэша пароля в куках и БД, а также сравнение неизвестного хэша, который был сгенерирован и неизвестного хэша в БД, если проверка не прошла, то удаляем куки
- setcookie('login','');
- setcookie('hash','');
- }
- unset($user_row,$check_user);
- }
Ну вот в принципе и всё, упрощённый алгоритм аутентификации, можно ещё туда добавить множество различных проверок, к примеру на ввод правильности логина и пароля, то есть разрешённые символы и т.д. и т.п.
© Филимошин В. Ю., 2011