Во-первых, просто отследите, вошел ли кто-то в систему. После этого мы позаботимся о функции «запомнить меня».
Чтобы узнать, вошел ли кто-то в систему, просто посмотрите на массив $_SESSION
. Все, что там есть, потому что вы положили это туда раньше. Итак, при обработке формы входа, если имя пользователя и пароль верны, вы сохраняете имя пользователя, идентификатор пользователя или что-то еще в сеансе ($_SESSION['username'] = $username;
).
Всякий раз, когда пользователь загружает любую страницу, вы просто проверяете
if (isset($_SESSION['username'])) {
// $_SESSION['username'] is logged in
} else {
// nobody is logged in
}
Нет необходимости хранить пароль в $_SESSION
(на самом деле в целях безопасности его лучше нигде не хранить, кроме хеширования в базе данных).
Теперь функция «запомнить меня»… Сначала несколько соображений:
- Любой пользователь может изменить файлы cookie своего браузера, поэтому вы должны быть уверены, что файл cookie, отправленный в приложение, не был изменен.
- Пользователи могут проверить это на общедоступных компьютерах (в библиотеках и т. д.), поэтому вам нужна система, которая сделает это недействительным.
- Если пользователь выходит из вашего приложения, запоминающий его файл cookie должен быть стерт.
Во-первых, представьте, что в файле cookie вы храните имя пользователя, которого нужно «запомнить» (ОЧЕНЬ НЕБЕЗОПАСНО!!). Это означает, что если какой-либо пользователь создаст файл cookie для вашего веб-приложения с содержимым «joe», ваше приложение будет думать, что пользователь joe запомнен на этом компьютере, поэтому предоставьте доступ этому злоумышленнику, как если бы он / она был joe. Итак, нам нужно каким-то образом зашифровать/хешировать cookie.
Что касается второго пункта, аннулирования «запомнить меня» на некоторых компьютерах, мы каким-то образом будем использовать пароль. Если какой-то пользователь хочет сделать недействительными все компьютеры, на которых он/она мог установить флажок «запомнить меня», все, что ему/ей нужно сделать, это изменить свой пароль. Это также означает, что если он/она изменит свой пароль, все сохраненные логины для его/ее учетной записи будут аннулированы по той же самой причине. Но лучше перестраховаться, чем потом сожалеть...
Итак, когда вы обрабатываете логин и имя пользователя и пароль верны, и опция «запомнить меня» отмечена, в дополнение к сохранению имени пользователя в сеансе вы сохраняете хэш имени пользователя и пароля (и немного соли, если вы будет) в файле cookie, который вы отправляете пользователю. Также вам необходимо сохранить в файле cookie имя пользователя в виде простого текста (или зашифрованного обратимым способом), чтобы узнать, какой пользователь пытается «войти в систему» через файл cookie, и проверить хэш имени пользователя и пароля в файле cookie с помощью хэша логин и пароль в базе. Если эта проверка верна, вы затем сохраняете имя пользователя в сеансе и больше не проверяете файл cookie этого пользователя (по крайней мере, для этого сеанса).
Итак, в целом ваш код может выглядеть так:
логин.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 или ша, соленый md5 или ша (лучше) или какой-нибудь трудоемкий метод, такой как иглобрюх (рекомендуется). Для хеширования куки я использовал простой md5, но вы можете выбрать любой из методов, описанных ранее.
Я думаю, это все.
person
Carlos Campderrós
schedule
23.02.2011