Концепция системы логики и логика? - PullRequest
5 голосов
/ 23 февраля 2011

Я хочу знать процесс, которым обычно следуют веб-приложения для поддержания входа между несколькими запросами, а также как они управляют вещами с помощью COOKIES.

В форме входа в систему я предоставляю функцию "Запомнить меня".

При входе пользователя в систему я проверяю правильность имени пользователя и пароля из базы данных. Если он действителен, тогда я проверяю, выбран ли «Запомнить меня», если да, то сохраняя имя пользователя и пароль в сеансе в зашифрованном формате. И, наконец, сохранение имени пользователя и пароля в СЕССИИ.

Когда пользователь переходит с одной страницы на другую, сначала я запускаю скрипт проверки входа в систему, который проверяет, есть ли какое-либо значение в файлах cookie, затем проверяет это имя пользователя и пароль из базы данных, чтобы проверить их действительность. Если в cookie нет значения, а в сеансе есть какое-то значение, я извлекаю значение сеанса, а не проверяю его из БД.

Я не проверяю сессионное значение формы db, чтобы не нажимать на db без необходимости, ускорить процесс. В случае файлов cookie их можно изменить, поэтому необходима проверка.

Это моя концепция, правильно? Это способ пойти и обычно сайт, как SO, и другие работы на этот вид метода?

Или веб-сайты проверяют подлинность входа в систему при каждой загрузке страницы, независимо от того, находится ли она в сеансе или в файлах cookie?

Пожалуйста, проверьте и изложите свои мысли и концепции для этого сценария.

Спасибо!

1 Ответ

14 голосов
/ 23 февраля 2011

Во-первых, просто отследите, вошел ли кто-то в систему. После этого мы позаботимся о функции «запомнить меня».

Чтобы узнать, если кто-то вошел в систему, просто посмотрите на $_SESSION массив.Все, что есть, есть, потому что вы положили это там раньше.Таким образом, при обработке формы входа в систему, если имя пользователя и пароль верны, вы сохраняете имя пользователя, идентификатор пользователя или что-либо еще в сеансе ($_SESSION['username'] = $username;).

Всякий раз, когда пользователь загружает любую страницу, вы просто проверяете

if (isset($_SESSION['username'])) {
    // $_SESSION['username'] is logged in
} else {
    // nobody is logged in
}

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

Теперь, функция «запомнить меня» ... Во-первых, некоторые соображения:

  • Любой пользователь может изменить файлы cookie своего браузера, поэтому вы должны быть уверены, что файл cookie, отправленный в приложение, не был подделан.
  • Пользователи могут проверять это на общедоступных компьютерах (в библиотеках и т. П.), Поэтому вам нужна система для их аннулирования.
  • Если пользователь выходит из вашего приложения, cookie-файл запоминает его / еедолжен быть удален.

Во-первых, представьте, что в куки-файле вы сохраняете имя пользователя, которое нужно «запомнить» (ОЧЕНЬ БЕЗОПАСНО !!).Это означает, что если какой-либо пользователь создаст для вашего веб-приложения файл cookie с содержимым «joe», ваше приложение будет думать, что пользователь joe запомнен на этом компьютере, поэтому предоставьте доступ этому злоумышленнику, как если бы он был joe.Итак, нам нужно каким-то образом зашифровать / хэшировать cookie.

Во-вторых, при аннулировании «помни меня» на некоторых компьютерах мы будем каким-то образом использовать пароль.Если какой-либо пользователь хочет сделать недействительными все компьютеры, на которых он / она мог установить флажок «запомнить меня», все, что ему нужно сделать, - это сменить свой пароль.Это также означает, что если он / она изменяет свой пароль, все сохраненные логины для его / ее учетной записи будут аннулированы по той же самой причине.Но лучше, чем потом сожалеть ...

Итак, когда вы обрабатываете логин и имя пользователя и пароль верны, и опция "Запомнить меня" отмечена, в дополнение к сохранению имени пользователя в сеансе, высохраните хэш имени пользователя и пароля (и немного соли, если хотите) в файле cookie, который вы отправляете пользователю.Также вам необходимо сохранить в cookie имя пользователя в виде простого текста (или зашифровано обратимым образом), чтобы узнать, какой пользователь пытается «войти» через cookie, и проверить хэш имени пользователя и пароля в cookie с помощью хешаимя пользователя и пароль в базе данных.Если эта проверка верна, вы сохраняете имя пользователя в сеансе и больше не проверяете cookie этого пользователя (по крайней мере, для этого сеанса).

Итак, в целом ваш код может выглядеть следующим образом:

login.php

if (check_login($_POST['username'], $_POST['password'])) {
    // login correct
    $_SESSION['username'] = $_POST['username'];
    if (isset($_POST['remember_me'])) {
        // we hash the password because we **NEVER** store it in plain text anywhere
        // so when we would like to check if the cookie value is correct, we will not
        // be able to do so if the hash in the cookie was done from the plaintext
        // password.
        $value = sprintf('%s:%s', $_POST['username'], md5($_POST['username'].hash_password($_POST['password'])));
        setcookie('rememberme', $value);
    }
    redirect('/your/home/page.php'); // view Post/Redirect/Get design pattern
} else {
    // login incorrect, show error message and whatever...
}

в начале каждого php-файла (или лучше во включенном файле для загрузки вашего приложения)

if (isset($_SESSION['username'])) {
    // $_SESSION['username'] is logged in, proceed as you wish
} else if (isset($_COOKIE['rememberme'])) {
    // this user has checked the remember me feature some time ago in a previous login.
    // let's check if it is valid.
    list($username, $hash) = explode(':', $_COOKIE['rememberme']);

    // we need to get the password hash stored for this user (remember you **NEVER** store passwords in plain text
    $pwd_hash = obtain_password_hash_from_username($username);
    if ($hash == sprintf('%s:%s', $username, md5($username.$pwd_hash))) {
        // yeah, the user remembered is correct. We'll save it to the session to not do this shit again
        $_SESSION['username'] = $username;
    } else {
        // the cookie value is not correct so maybe an attacker is trying to fool us,
        // or the user changed his password. Whatever it is, we remove the cookie
        // because it's no longer valid
        setcookie('rememberme', '', time() - 3600);
    }

} else {
    // this user is neither logged in nor "remembered"
}

Способ хеширования пароля пользователя зависит от вас.Вам может понравиться обычный md5 или sha, соленый md5 или sha (лучше) или какой-то трудоемкий метод, например blowfish (рекомендуется).Для хеширования куки я использовал обычный md5, но вы можете выбрать любой из методов, описанных ранее.

Я думаю, что это все.

...