Как динамически выбирать алогоритм кодировщика пароля

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

  • YAML
    1
    2
    3
    4
    5
    # app/config/security.yml
    security:
        # ...
        encoders:
            Symfony\Component\Security\Core\User\User: sha512
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    <!-- app/config/security.xml -->
    <?xml version="1.0" encoding="UTF-8"?>
    <srv:container xmlns="http://symfony.com/schema/dic/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:srv="http://symfony.com/schema/dic/services"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
            http://symfony.com/schema/dic/services/services-1.0.xsd"
    >
        <config>
            <!-- ... -->
            <encoder class="Symfony\Component\Security\Core\User\User"
                algorithm="sha512"
            />
        </config>
    </srv:container>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    // app/config/security.php
    use Symfony\Component\Security\Core\User\User;
    
    $container->loadFromExtension('security', array(
        // ...
        'encoders' => array(
            User::class => array(
                'algorithm' => 'sha512',
            ),
        ),
    ));
    

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

В предыдущем примере, вы установили алогритм sha512 для Acme\UserBundle\Entity\User. Это может быть достаточно безопасно для обычного пользователя, но что, если вы хотите, чтобы ваши администраторы имели более сильные алгоритмы, например, bcrypt? Это можно сделать с помощью названных кодировщиков:

  • YAML
    1
    2
    3
    4
    5
    6
    7
    # app/config/security.yml
    security:
        # ...
        encoders:
            harsh:
                algorithm: bcrypt
                cost: 15
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    <!-- app/config/security.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <srv:container xmlns="http://symfony.com/schema/dic/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:srv="http://symfony.com/schema/dic/services"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
            http://symfony.com/schema/dic/services/services-1.0.xsd"
    >
    
        <config>
            <!-- ... -->
            <encoder class="harsh"
                algorithm="bcrypt"
                cost="15" />
        </config>
    </srv:container>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    // app/config/security.php
    $container->loadFromExtension('security', array(
        // ...
        'encoders' => array(
            'harsh' => array(
                'algorithm' => 'bcrypt',
                'cost'      => '15'
            ),
        ),
    ));
    

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

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

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface;

class User implements UserInterface, EncoderAwareInterface
{
    public function getEncoderName()
    {
        if ($this->isAdmin()) {
            return 'harsh';
        }

        return null; // использовать кодировщик по умолчанию
    }
}

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.