В этом популярном решении для Persistent Login Cookies, которое включает в себя создание случайного 128-битного «токена» для сохранения в Cookie пользователя, Йенс Роланд рекомендует:
И НЕ УСТАНАВЛИВАЙТЕ ПОСТОЯННУЮ ЛОГИНУЮ КУХНИ (ТОКЕН) В ВАШЕЙ БАЗЕ ДАННЫХ, ТОЛЬКО ХАШ ЭТО! Маркер входа – это эквивалент пароля, поэтому, если злоумышленник получил доступ к вашей базе данных, он может использовать токены для входа в какую-либо учетную запись, точно так же, как если бы они были комбинациями паролей с открытым текстом. Поэтому при хранении постоянных токенов входа используйте сильное соленое хеширование (bcrypt / phpass).
- Как вы разрешаете клиентам регистрироваться на вашем сайте с помощью своей учетной записи Google?
- Автозапуск phpMyAdmin
- Вход Android с сеансом Token: как пользовательские логины и остается в сеансе до выхода из системы
- Является ли сравнение строк в MySQL уязвимым для временных атак?
- Ошибка ввода формы входа в PHP
Но как вы проверяете токен Cookie против bcrypted Token в БД, чтобы подтвердить, что вход в Cookie действителен, когда bcrypting Token Cookie всегда даст другой результат (так как bcrypting всегда использует случайную соль)?
Другими словами, вы не можете просто шифровать токен Cookie и искать совпадение в БД, так как вы его никогда не найдете, так как вы на самом деле сопоставляете его с хеш-версией в БД в соответствии с рекомендуемым решением («The сервер хранит таблицу number-> username association, которая проверяется на достоверность файла cookie. ")?
Редактировать:
Имейте в виду, что в соответствии с рекомендуемым решением, связанным выше, у одного пользователя может быть несколько Cookies / токенов для разных устройств. Я упоминаю об этом, потому что был отправлен ответ (который с тех пор был удален), который предположил, что это только один токен на пользователя.
Как упоминалось в предыдущем ответе, bcrypt сохраняет случайную соль как часть хэша, поэтому каждая запись маркера в вашей базе данных будет включать как random_salt
и hashed_token
.
При аутентификации «cookie cookie» «Запомнить меня» (который должен состоять из userid
и token
) вам потребуется выполнить итерацию по каждой из записей маркера для этого идентификатора пользователя (обычно только одна запись, не более нескольких) и проверить каждый отдельно используя сохраненную случайную соль:
foreach (entry in stored_tokens_for_user) { if (entry.hashed_token == bcrypt(cookie.token, entry.random_salt)) return true; } return false;
(если ваша база данных имеет встроенную поддержку bcrypt как часть синтаксиса запроса, вы можете создать подготовленный оператор, чтобы сделать это за вас)