Разработка безопасной системы cookie для автоматического входа в систему на PHP

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

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

Один из моих друзей предлагает создать таблицу db, в которой хранятся идентификатор сеанса, IP-адрес пользователя, информация о браузере и т. Д., А затем сравнивать всю эту информацию, когда пользователь снова переходит на веб-сайт.

Мне кажется, что иметь отдельный стол для этого - слишком большая проблема. Есть другой способ сделать это? Может токенами или чем-то в этом роде?


person CodeCrack    schedule 29.09.2011    source источник


Ответы (3)


Чем более безопасным будет этот печально известный файл cookie, тем больше проблем он доставит вам. Если ваши пользователи должны быть особенно защищены, вам придется пойти на самый хлопотный подход.

Вам следует принимать этот файл cookie с https только в том случае, если вы хотите быть максимально безопасными. Если файл cookie принимается через http, его можно перехватить и украсть.

Я бы рекомендовал, чтобы файл cookie вообще не содержал пользовательских данных (токен, как вы предложили). К сожалению, для этого потребуется другая таблица. Когда пользователь входит в систему и выбирает «сохранить логин», создайте запись в этой таблице. Запись может быть любым бессмысленным значением (например, md5(uniqid('', true));. Этот токен может быть уникальным в БД и соответствовать идентификатору пользователя.

Когда пользователь посещает ваш веб-сайт, вы можете проверить значение этого файла cookie, получить пользователя, которому он принадлежит, и войти в него. На этом этапе вы уничтожаете старый токен и создаете новый. «Уничтожить» может означать многое. Вы можете полностью удалить его из БД или установить флаг, отключающий токен. Вы можете разрешить использовать один и тот же токен несколько раз, если файл cookie получен, но аутентификация по какой-то причине не проходит, но я думаю, что это небезопасно. Вы также можете сохранить временную метку токена и принимать ее только в том случае, если это был ограниченный период времени (например, 30 дней).

Как указывает ваш друг, вы можете хранить другую информацию, такую ​​как пользовательский агент, IP-адрес и т. Д., Но они могут измениться даже при использовании того же браузера (особенно с мобильным телефоном), и если постоянный вход пользователя не принимается из-за этого , это могло быть неприятно и неудобно для них.

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

person Explosion Pills    schedule 29.09.2011
comment
Когда пользователь посещает ваш веб-сайт, вы можете проверить значение этого файла cookie, узнать пользователя, которому он принадлежит, и войти в систему. Как лучше всего это сделать? Просто перенаправить их на защищенную страницу с их пользователем / перейти из БД? - person CodeCrack; 29.09.2011
comment
@CodeCrack У вас есть полный контроль над тем, аутентифицирован ли пользователь или нет, поэтому на самом деле лучшего способа нет. Просто сделайте то же самое, что и после того, как они введут свое имя пользователя / пароль. Вероятно, у вас есть (или вы можете создать) функцию или что-то под названием complete_login(), которые необходимы для сеанса. - person Explosion Pills; 29.09.2011
comment
Какая польза от уничтожения старого токена при входе в систему? Я предполагаю, что в этот момент клиенту будет передан новый, не так ли? - person kcode; 30.04.2012
comment
@Uwe просто дополнительный шаг безопасности - зачем держаться за то, что аутентифицируется дольше, чем это необходимо? Вероятно, есть и более веские причины, но, например, если злоумышленник получит ваш токен, а вы никогда его не уничтожите, он может навсегда войти в систему под вашим именем. - person Explosion Pills; 30.04.2012
comment
Привет всем, когда файл cookie пользователя A копируется (лицом, имеющим разрешение на доступ к компьютеру пользователя A) и вставляется на любой компьютер этого конкретного веб-сайта, он в конечном итоге отображает всю информацию пользователя A человеку, который получил локальный доступ Пользователю Компьютер. Как этого не допустить. Любое сообщество идей? - person anna poorani; 09.08.2017

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

function gen_uniqueIdent($length=32){
    $alphabet = str_split('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789');
    $key = '';
    for($loop=0;$loop<$length;$loop++){
        $i = mt_rand(0,count($alphabet)-1);
        $key.= $alphabet[$i];
    }
    return $key;
}

Присвойте это значение файлу cookie пользователя при входе в систему. Затем сохраните это в базе данных:

function save_ident($identFromFunctionAbove,$authenticated_user_id){
    //hash this with something unique to the user's machine
    $hashed = md5($identFromFunctionAbove . $_SERVER['REMOTE_ADDR']);
    /** Some actions to remember this hash **/
}

сохраните это в базе данных, соответствующей идентификатору пользователя, например user_id.

Теперь, после проверки файла cookie пользователя, вы можете просто:

function validateCookie(){
    $ident = $_COOKIE['yourCookieName'];
    $hashed = md5($ident . $_SERVER['REMOTE_ADDR']);
    /** Check if this hashed value exists in db, if it does, authenticate user **/
}

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

Конечно, это очень просто и не учитывает коллизии md5 или идентификаторов. Тем не менее, получение двух 32-символьных случайных сгенерированных строк, которые будут такими же, как и ранее сгенерированная, является довольно незначительным шансом.

person jabbany    schedule 29.09.2011
comment
Когда пользователь входит в систему с помощью файла cookie, нужно ли мне вручную устанавливать переменную SESSION, если я использую ее для чего-то, или еще лучше, как восстанавливается сеанс? - person CodeCrack; 29.09.2011
comment
@CodeCrack Фактически, упомянутый выше метод создает ваш собственный метод управления сеансом в php. Итак, в принципе, да, вам нужно вручную установить переменную SESSION, чтобы использовать сеансы PHP с этим методом. - person jabbany; 30.09.2011

То, как я делал это ранее, заключается в хранении MD5-хэша пароля, а не фактического пароля.

На стороне сервера вам необходимо проверить, исходит ли вход из файла cookie, а затем проверить, совпадает ли хэш с паролем в вашей базе данных после его хеширования с помощью MD5.

Таким образом, если кто-то взломает компьютер пользователя, он никогда не сможет узнать значение пароля, однако он все равно может использовать этот файл cookie для аутентификации только на вашем сервере.

Вы можете сделать это более безопасным, установив срок действия куки-файла через x дней, поэтому в случае кражи куки-файла theif может получить доступ только на этот период.

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

person Jase Whatson    schedule 29.09.2011
comment
Пароли уже должны быть хешированы перед сохранением как есть. - person Explosion Pills; 29.09.2011
comment
Да, именно плюс они могут использовать таблицу Rainbow, чтобы сбить пароль. - person CodeCrack; 29.09.2011