Авторизация (php + mysql) и запоминание пользователей

Аватара пользователя
SLITE
Сообщения: 204
Зарегистрирован: 01 янв 2010
1. Таблица БД с пользователями

Мы будем использовать очень краткий вариант. Структура будет такова:

Код: Выделить всё

id smallint(8) unsigned NOT NULL auto_increment,
login varchar(50) NOT NULL default '',
password varchar(32) NOT NULL default ''


Размер поля password — 32 символа. Т.к. мы бедм хранить в нем хеш пароля, а не сам пароль в чистом виде.

2. Авторизация и вход пользователей

Для начала мы отрисуем форму, с помомью которой пользователь сможет передать нам свой логин и пароль.

Код: Выделить всё

<form action="login.php" method="post">
    <table>
        <tr>
            <td>Логин:</td>
            <td><input type="text" name="login" /></td>
        </tr>
        <tr>
            <td>Пароль:</td>
            <td><input type="password" name="password" /></td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="Войти" /></td>
        </tr>
    </table>
</form>

После ввода пользователем данных, мы проверяем его логин и пароль.

Так как мы договорились не хранить пароль в чистом виде, будем ставнивать хеш введённого пароля с тем, что хранится у нас в базе.

Код: Выделить всё

if (isset($_POST['login']) && isset($_POST['password']))
{
    $login = mysql_real_escape_string($_POST['login']);
    $password = md5($_POST['password']);

    // делаем запрос к БД
    // и ищем юзера с таким логином и паролем

    $query = "SELECT `id`
            FROM `users`
            WHERE `login`='{$login}' AND `password`='{$password}'
            LIMIT 1";
    $sql = mysql_query($query) or die(mysql_error());

    // если такой пользователь нашелся
    if (mysql_num_rows($sql) == 1) {
        // то мы ставим об этом метку в сессии (допустим мы будем ставить ID пользователя)

        $row = mysql_fetch_assoc($sql);
        $_SESSION['user_id'] = $row['id'];

        // не забываем, что для работы с сессионными данными, у нас в каждом скрипте должно присутствовать session_start();
    }
    else {
        die('Такой логин с паролем не найдены в базе данных. И даём ссылку на повторную авторизацию.');
    }
}

3. Кто авторизован, а кто нет?

Итак мы определились, что авторизованные пользователи — те, у которых указан $_SESSION['user_id']
Те, у кого нет $_SESSION['user_id'], мы будем считать гостями.


Пример использования:

Код: Выделить всё

if (isset($_SESSION['user_id'])) {
    // показываем защищенные от гостей данные.
}
else {
    die('Доступ закрыт, даём ссылку на авторизацию.');
}

4. Как реализовать "запомнить меня на этом компьютере"?

Здесь, помимо сессий, мы будем использовать куки.
О куках обязательно нужно почитать у нас в FAQ.

Сессии не постоянны и данные в них хранятся только на время работы пользователя со скриптом. Поэтому, чтобы пользователь оставался залогиненым после того, как он закрыл и снова открыл на нашей странице свой браузер — необходимо сохранять его авторизационные данные в куках (они хранятся на его компьютере в браузере).
Мы будем записывать в куки пользователя его логин и хеш пароля. (как записывать что-то в куки, читайте выше по ссылке)
В нашем скрипте проверка пользовательских данных в куках будет выглядеть так:

Код: Выделить всё

// если пользователь не авторизован
if (!isset($_SESSION['user_id'])) {
    // то проверяем его куки
    // вдруг там есть логин и пароль к нашему скрипту

    if (isset($_COOKIE['login']) && isset($_COOKIE['password'])) {
        // если же такие имеются
        // то пробуем авторизовать пользователя по этим логину и паролю
        $login = mysql_real_escape_string($_COOKIE['login']);
        $password = mysql_real_escape_string($_COOKIE['password']);

        // и по аналогии с авторизацией через форму:

        // делаем запрос к БД
        // и ищем юзера с таким логином и паролем

        $query = "SELECT `id`
                FROM `users`
                WHERE `login`='{$login}' AND `password`='{$password}'
                LIMIT 1";
        $sql = mysql_query($query) or die(mysql_error());

        // если такой пользователь нашелся
        if (mysql_num_rows($sql) == 1) {
            // то мы ставим об этом метку в сессии (допустим мы будем ставить ID пользователя)

            $row = mysql_fetch_assoc($sql);
            $_SESSION['user_id'] = $row['id'];

            // не забываем, что для работы с сессионными данными, у нас в каждом скрипте должно присутствовать session_start();
        }
        else {
            // только мы не будем давай ссылку на форму авторизации
            // вдруг человек и не хочет был авторизованым
            // а пришел просто поглядеть на наши страницы как гость
        }
    }
}

Соль в пароле или как усложнить жизнь хакеру

Пароль можно подобрать по его хешу, зная алгоритм хеширования. Существует много баз, где пароли сопоставлены с их хешами.

Поэтому, простым движением руки, мы можем немного сложнить задачу людям, которые соберутся подбирать пароль по его хешу.
Можно брать двойной хеш (например, md5(sha1('password'))) или использовать так называемую "соль" (salt).
Пример использования соли: md5(md5('password') . 'secret_code');
secret_code — это и есть соль, то есть мы тупо к паролю добавляем какой-то набор символов (желательно ещё и запомнить, какой набор символов мы добавляем ;)).

Итак, для такого метода хранения пароля мы немного изменим таблицу БД с пользователями:

Код: Выделить всё

id smallint(8) unsigned NOT NULL auto_increment,
login varchar(50) NOT NULL default '',
password varchar(32) NOT NULL default '',
salt varchar(3) NOT NULL default ''



Здесь мы будем использовать соль из 3 символов.

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

Рассмотрим пример:
— мы регистрируем пользователя: md5 с паролем password и солью 8f*
— получаем его хеш, используя md5(md5('password') . '8f*')
— записываем пользователя в таблицу, получаем:
1 | md5 | 84cd3e7ff13bbaed1c1db91671844bcc | 8f*
— при входе пользователя через фому, немного изменим наш код:


Код: Выделить всё

// дня начала вытащим из таблицы с пользователями соль для логина, который был введен
$login = mysql_real_escape_string($_POST['login']);

$query = "SELECT `salt`
            FROM `users`
            WHERE `login`='{$login}'
            LIMIT 1";
$sql = mysql_query($query) or die(mysql_error());

if (mysql_num_rows($sql) == 1) {
    $row = mysql_fetch_assoc($sql);

    // итак, вот она соль, соответствующая этому логину:
    $salt = $row['salt'];

    // теперь хешируем введенный пароль как надо и повторям шаги, которые были описаны выше:
    $password = md5(md5($_POST['password']) . $salt);

    // и пошло поехало...
}
else {
    die('пользователь с таким логином не найден, даём ссылку на повторную авторизацию');
}

Источник:www.pyha.ru

Вернуться в «PHP»