как создать безопасную систему входа на php, позволяющую мне оставаться в системе?

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

Я хотел бы предложить опцию на экране входа в систему с надписью «держать меня в системе в течение всего дня». Как сделать это безопасным способом?


person pixeline    schedule 18.12.2009    source источник


Ответы (3)


Во-первых: настройте директиву session.cookie_lifetime либо в php.ini, файлы конфигурации или через session_set_cookie_params().

Затем сохраните имя пользователя и хеш-значение пароля в сеансе и проверяйте этот вход на каждой странице. Пока он еще действителен, они остаются в системе.

Естественное истечение срока действия файла cookie сеанса обычно должно поддерживать порядок, так как у вас не будет выхода из системы в середине сеанса (если, конечно, звездочки совпадают), если они будут поддерживать его в активном состоянии. Однако в противном случае я бы посчитал решение eCartoth вторым, так как вы могли бы просто добавить вторую строку в оператор if:

if (my_validate_user_function($_SESSION['username'],$_SESSION['passhash']) 
    && $_SESSION['deathstamp'] > time()
) {
    // user is logged in again, oh boy!
}
else {
    // send in the death robots
    header('Location: /login.php',true,302);
}

РЕДАКТИРОВАТЬ: Одна вещь, которую вы, возможно, захотите рассмотреть, - это фиксация сеанса и / или захват сеанса. Чтобы предотвратить это, я бы порекомендовал одно (или оба) из двух решений:

  1. сохранить IP-адрес пользователя в сеансе
  2. используйте session_regenerate_id() после каждой успешной попытки входа в систему.
person Dereleased    schedule 18.12.2009
comment
Использование SESSIONS - единственный способ создать хорошую систему безопасности, +1 - person TravisO; 18.12.2009
comment
Можете ли вы явным образом указать свое последнее изменение: зачем сохранять IP-адрес пользователя и повторно создавать идентификатор сеанса? - person pixeline; 28.12.2009
comment
PHP принимает несколько механизмов для указания идентификатора сеанса (например, строки запроса), что позволяет кому-то установить заранее определенный идентификатор сеанса, отправить его по URL-адресу ничего не подозревающей жертве, и после входа в систему злонамеренный пользователь может использовать тот же сеанс. ID для подделки учетных данных законного пользователя, которые хранятся в сеансе. Сохраняя IP и / или регенерируя идентификатор сеанса при каждом запросе, фиксированный идентификатор сеанса злонамеренного пользователя, по сути, бесполезен. Прочтите это для получения дополнительной информации: en.wikipedia.org/wiki/Session_fixation - person Dereleased; 28.12.2009
comment
проверка действительности сеанса с базой данных каждый раз может снизить производительность приложения, так как в этом случае мы будем каждый раз выполнять 1-2 запроса к базе данных. Или это правильный путь, и большинство популярных веб-сайтов работают над этой концепцией? - person Prashant; 23.02.2011
comment
ваша вторая точка использует session_regenerate_id () после каждой успешной попытки входа в систему. является обязательным. кроме того, нам нужно помнить, что на общем сервере вы можете вместо этого сохранить сеанс в базе данных просто по той причине, что файлы cookie сеанса сохраняются на сервере в виде плоских файлов, которые могут быть сохранены по некоторым причинам! - person ; 17.07.2011
comment
@Abhishek - Очень важный момент об общих хостах. Еще один случайный лакомый кусочек: если вы используете класс для управления сеансом, вам необходимо убедиться, что вы вызываете метод write_close в своей функции __destruct(), иначе объект может быть уничтожен сборкой мусора до сохранения сеанса. - person Dereleased; 18.07.2011

Когда вы говорите «держать меня в системе весь день», я предполагаю, что вы имеете в виду только эту конкретную машину, верно? Вы можете использовать таблицу mysql для запоминания «времени входа в систему» ​​или отметки времени, когда этот вход в систему больше не будет действителен, если они решат оставаться в системе весь день. Затем добавьте сценарий в начало вашего кода, который извлекает идентификатор этого пользователя из переменных сеанса. Сравните текущую временную метку этого пользователя с сохраненными «последними действительными ts», и если это время прошло, вы знаете, что они должны выйти из системы, после чего вы стираете сеанс и заставляете пользователя снова войти в систему. Этот метод означает, что они фактически не выйдут из системы, пока они не попытаются сделать что-то после этого момента, но им это будет казаться так. Кроме того, вместо использования базы данных mysql вы также можете сохранить этот последний действительный TS в переменной сеанса.

Так, например, когда пользователь впервые входит в систему с помощью «держать меня в системе выбран весь день»:

$_SESSION['log_me_out_at'] = strtotime(date("Y-m-d ")."23:59:59");

Затем каждый раз, когда в вашей системе осуществляется доступ к странице:

if( $_SESSION['log_me_out_at'] < time() ){
  unset($_SESSION['user_is_accepted_in']);
}
person eCaroth    schedule 18.12.2009
comment
Забыл упомянуть, что, делая это с помощью переменных сеанса, вы ограничиваете доступ к этому конкретному компьютеру, и, поскольку переменные сеанса никак не доступны со стороны клиента, вам не нужно беспокоиться о том, что эти данные будут изменены вне вашего контроля. - person eCaroth; 18.12.2009
comment
проблема с вашей логикой в ​​том, что переменные сеанса не должны быть настроены на работу в течение всего дня! Таким образом, они истекают до фактических 24 часов, что вынуждает пользователя снова войти в систему. - person pixeline; 18.12.2009
comment
Затем установите файл cookie на машине пользователя с его именем, срок действия которого будет до конца этого дня. Сохраните запись в таблице mysql с их uname и IP-адресом, на котором они вошли в систему, и если они получают доступ к приложению с этого IP-адреса, а временная метка все еще действительна, пусть они в else заставят их снова войти в систему. - person eCaroth; 18.12.2009
comment
@pixeline: проблема с вашей логикой в ​​том, что тайм-аут файла cookie / сеанса настраивается. - person Dereleased; 18.12.2009
comment
э, я имел в виду: я не хочу изменять время истечения сеанса сервера для всего сервера, только для моего приложения. Но ваш ответ выглядит многообещающим. я смотрю на это. - person pixeline; 18.12.2009

Одним из вариантов может быть настройка таблицы MySQL, которая сохраняет переменные сеанса и связывает их с IP-адресами и сроком действия, но я не уверен во всех деталях того, как это будет реализовано.

Самый простой (но не рекомендуемый) способ сделать то, что вы ищете, - это установить $_COOKIE с именем пользователя и паролем на компьютере, которые ваш сайт затем будет проверять, когда пользователь входит в систему. .

Для дополнительной безопасности лучше всего сохранить только один файл cookie в качестве соленого MD5-хэша данных пользователя, чтобы предоставить потенциальному хакеру меньше информации о данных учетной записи пользователя. Продолжительность может быть установлена ​​при установке cookie; На php.net есть достаточно полная документация о том, как это сделать.

person Kaji    schedule 18.12.2009
comment
Пожалуйста, не помещайте пароль пользователя в куки - person Simon; 18.12.2009
comment
Согласен, поэтому я последовал за предложением хеширования. Я настоятельно рекомендую не использовать тот же хэш, который вы, вероятно, используете для хранения пароля пользователя в первую очередь, так как это было бы почти так же плохо. Основывайте его на различных уникальных данных или, по крайней мере, используйте для этого другую соль. - person Kaji; 18.12.2009