Разработка безопасной файловой системы cookie для автоматического входа в PHP - PullRequest
15 голосов
/ 29 сентября 2011

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

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

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

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

Ответы [ 3 ]

26 голосов
/ 29 сентября 2011

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

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

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

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

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

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

4 голосов
/ 29 сентября 2011

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

0 голосов
/ 29 сентября 2011

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

На стороне сервера вам нужно проверить, приходит ли логин из куки, а затем проверить, еслихеш совпадает с паролем в вашей базе данных после того, как он был хеширован с помощью MD5

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

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

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

...