Як мігрувати хеш пароля
Дата оновлення перекладу 2023-06-22
Як мігрувати хеш пароля
Для того щоб захищати паролі, рекомендовано зберігати їх, використовуючі останні
алгоритми хешування. Це означає, що якщо у вашій системі підтримується кращий алгоритм
хешування, пароль користувача має бути хешований повторно, використовуючи новіший
алгоритм, та збережений. Це можливо з опцією migrate_from
:
- Сконфігуруйте новий хешувальник, використовуючи "migrate_from"
- Оновіть пароль
- За бажанням, Запустіть міграцію паролів з користувацького хешувальника
Сконфігуруйте новий хешувальник, використовуючи "migrate_from
Коли стає доступним кращий алгоритм хешування, ви маєте залишити існуючий(і) хешувальник(и),
перейменувати його, а потім визначити новий. Встановіть опцію migrate_from
у новому
хешувальнику, щоб вказати на старий(і) успадкований(і) хешувальник(и):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# config/packages/security.yaml
security:
# ...
password_hashers:
# хешувальник, використовуваний у минулому для деяких користувачів
legacy:
algorithm: sha256
encode_as_base64: false
iterations: 1
App\Entity\User:
# новий хешувальник, разом з його опціями
algorithm: sodium
migrate_from:
- bcrypt # використовує хешувальник "bcrypt" з опціями за замовчуванням
- legacy # використовує хешувальник "legacy", сконфігурований вище
З цим налаштуванням:
- Нові користувачі будуть хешуватися з новим алгоритмом;
- Кожний раз при вході у систему користувача, чий пароль все ще зберігається з використанням старого алгоритму, Symfony верифікуватиме пароль зі старим алгоритмом, а потім повторно хешувати та оновлювати пароль, використовуючи новий алгоритм.
Tip
Хешувальники auto, native, bcrypt і argon автоматично вмикають міграцію
паролів, використовуючи список алгоритмів migrate_from
:
- PBKDF2 (який використовує hash_pbkdf2);
- Хеш (який використовує hash)
Обидва використовують налаштування hash_algorithm
в якості алгоритму. Рекомендовано
використовувати migrate_from
замість hash_algorithm
, окрім випадків використання
хешувальника auto.
Оновіть пароль
Після успішного входу у систему, система Security перевіряє, чи доступний кращий алгоритм для хешування пароля користувача. Якщо доступний, то вона хешує правильний пароль, використовуючи новий хеш. Якщо ви використовуєте аутентифікатор Guard, спочатку вам потрібно надати оригінальний пароль системі Security .
Ви можете підключити поведінку оновлення, реалізувавши, як цей новохешований пароль має бути збережений:
- За використання сутності постачальника користувачів Doctrine
- За використання сутності користувацького постачальника користувачів
Після цього ви закінчили, і паролі завжди будуть хешовані максимально безпечно!
Надайте пароль за використання Guard
Коли ви використовуєте користувацький аутентифікатор guard,
вам потрібно реалізувати PasswordAuthenticatedInterface.
Цей інтерфейс визначає метод getPassword()
, який повертає пароль для цього запиту входу у систему.
Цей пароль використовується у процесі міграції:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Security/CustomAuthenticator.php
namespace App\Security;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
// ...
class CustomAuthenticator extends AbstractGuardAuthenticator implements PasswordAuthenticatedInterface
{
// ...
public function getPassword($credentials): ?string
{
return $credentials['password'];
}
}
Оновіть пароль за використання Doctrine
За використання сутності постачальника користувачів,
реалізуйте PasswordUpgraderInterface у
UserRepository
(див. документацію Doctrine, щоб отримати інформацію про те, як створити
цей клас, якщо він ще не створений). Цей інтерфейс реалізує зберігання новоствореного хешу
паролів:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// src/Repository/UserRepository.php
namespace App\Repository;
// ...
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
class UserRepository extends EntityRepository implements PasswordUpgraderInterface
{
// ...
public function upgradePassword(UserInterface $user, string $newHashedPassword): void
{
// встановіть новохешований пароль в обʼєкті User
$user->setPassword($newHashedPassword);
// виконайте запити до DB
$this->getEntityManager()->flush();
}
}
Оновіть пароль за використання користувацького постачальника користувачів
Якщо ви використовуєте користувацького постачальника користувачів, реалізуйте PasswordUpgraderInterface у постачальнику користувачів:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// src/Security/UserProvider.php
namespace App\Security;
// ...
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
class UserProvider implements UserProviderInterface, PasswordUpgraderInterface
{
// ...
public function upgradePassword(UserInterface $user, string $newHashedPassword): void
{
// встановіть новохешований пароль в обʼєкті User
$user->setPassword($newHashedPassword);
// ... зберегти новий пароль
}
}
Запустіть міграцію паролів з користувацького хешувальника
Якщо ви використовуєте користувацький хешувальник паролів, ви можете викликати міграцію
паролів, повернувши true
у методі needsRehash()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// src/Security/CustomPasswordHasher.php
namespace App\Security;
// ...
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class CustomPasswordHasher implements UserPasswordHasherInterface
{
// ...
public function needsRehash(string $hashed): bool
{
// перевірити, чи хешується поточний пароль з використанням застарілого хешувальника
$hashIsOutdated = ...;
return $hashIsOutdated;
}
}