Как использовать разные алгоритмы хеширования пароля для каждого пользователя

Дата обновления перевода 2021-09-29

Как использовать разные алгоритмы хеширования пароля для каждого пользователя

Обычно, один хешировщик паролей используется для всех пользователей, сконфигурированный таким образом, чтобы применяться ко всем экземплярам конкретного класса:

1
2
3
4
5
6
7
# config/packages/security.yaml
security:
    # ...
    password_hashers:
        App\Entity\User:
            algorithm: auto
            cost: 12

Другая опция - использовать "именованный" хешировщик, а затем выбрать, какой хешировщик вы хотите использовать, динамически.

В предыдущем примере, вы установили алгоритм auto для App\Entity\User. Это может быть достаточно безопасно для обычного пользователя, но что если вы хотите, чтобы у ваших админов был более мощный алгоритм, например, auto с более высокой ценой. Это можно сделать с помощью именованных хешировщиков:

1
2
3
4
5
6
7
# config/packages/security.yaml
security:
    # ...
    password_hashers:
        harsh:
            algorithm: auto
            cost: 15

Note

Если вы работаете на PHP 7.2+ или установили расширение libsodium, то рекомендованный к использованию алгоритм хеширования - Sodium .

Это создает хешировщик под названием harsh. Для того, чтобы экземпляр User использвал его, класс должен реализовывать PasswordHasherAwareInterface. Интерфейс требует одного метода - getPasswordHasherName() - который должен возвращать имя хешировщика для использования:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Entity/User.php
namespace App\Entity;

use Symfony\Component\PasswordHasher\Hasher\PasswordHasherAwareInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class User implements UserInterface, PasswordHasherAwareInterface
{
    public function getPasswordHasherName(): ?string
    {
        if ($this->isAdmin()) {
            return 'harsh';
        }

        return null; // use the default hasher
    }
}

Если вы создали собственный хеширофщик паролей, реализуя PasswordHasherInterface, вы должны зарегистрировать для него сервис, чтобы использовать его, как именованный хешировщик:

1
2
3
4
5
6
# config/packages/security.yaml
security:
    # ...
    password_hashers:
        app_hasher:
            id: 'App\Security\Hasher\MyCustomPasswordHasher'

Это создает хешировщик под названием app_hasher из сервиса с ID App\Security\Hasher\MyCustomPasswordHasher.