Я хочу внедрить систему аутентификации на основе токенов, которая будет устойчива к атакам инсайдеров. То есть тот, кто имеет доступ только для чтения к коду и базе данных, не должен иметь возможность использовать чужой токен. Это означает, что JWT - это не тот путь, потому что, если кто-то знает секретный ключ подписей токенов (который хранится в виде простого текста на сервере), они могут скомпрометировать токены всех (при условии, что они знают полезную нагрузку пользователя). ). Кроме того, я хочу реализовать нечто более простое, чем OpenID / OAuth.
Таким образом, я подумал о том, чтобы иметь маркеры доступа для каждого пользователя, хранящегося в базе данных. Каждый из них будет иметь продолжительность жизни 1 день. Но если вы знаете маркер пользователя, одного дня более чем достаточно, чтобы сделать что-то неприятное, например, удалить учетную запись. Поэтому я хочу добавить еще один уровень безопасности и хэшировать токены в базе данных.
Проблема в том, что функция PHP * password_hash()
использует соль, поэтому она не является детерминированной. Это означает, что я не могу этого сделать:
// Insert a new user
$token = generateToken(size=32);
$tokenHash = password_hash($token, PASSWORD_DEFAULT);
$sql = "
INSERT INTO `User` (username, password_hash, token_hash)
VALUES (:username, :password_hash, :token_hash)
";
$stmt->prepare($sql);
$stmt->execute([
":username" => $username,
":password_hash" => $paswordHash
":token_hash" => $tokenHash
]);
// Find an user with their token
$tokenHash = password_hash($token, PASSWORD_DEFAULT);
$sql = "SELECT * FROM `User` WHERE token_hash = :token_hash";
$stmt = $db->prepare($sql);
$stmt->execute([":token_hash" => $tokenHash]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
Действительно, $tokenHash
на практике никогда не будет равно значению, хранящемуся в базе данных, и правильная функция для этого сравнения - password_verify()
,Но поиск всех пользователей базы данных и использование password_verify()
для каждого из них было бы слишком неэффективным.
Как правильно найти пользователя (или, в более общем случае, запись базы данных), используя хешированное значениев своих колонках?
Спасибо за помощь.