User Providers

User providers (re)load users from a storage (e.g. a database) based on a "user identifier" (e.g. the user's email address or username). See Security for more detailed information when a user provider is used.

ユーザープロバイダーは、「ユーザー識別子」(ユーザーの電子メールアドレスやユーザー名など)に基づいて、ストレージ(データベースなど)からユーザーを(再)ロードします。 userprovider を使用する場合の詳細については、Security を参照してください。

Symfony provides several user providers:

Symfony はいくつかのユーザープロバイダーを提供します:
Entity User Provider
Loads users from a database using Doctrine;
Doctrine を使用してデータベースからユーザーをロードします。
LDAP User Provider
Loads users from a LDAP server;
LDAP サーバーからユーザーをロードします。
Memory User Provider
Loads users from a configuration file;
構成ファイルからユーザーをロードします。
Chain User Provider
Merges two or more user providers into a new user provider.
2 つ以上のユーザー プロバイダーを新しいユーザー プロバイダーにマージします。

Entity User Provider

This is the most common user provider. Users are stored in a database and the user provider uses Doctrine to retrieve them.

これは、最も一般的なユーザー プロバイダーです。ユーザーはデータベースに保存され、ユーザー プロバイダーは Doctrine を使用してユーザーを取得します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# config/packages/security.yaml
security:
    providers:
        users:
            entity:
                # the class of the entity that represents users
                class: 'App\Entity\User'
                # the property to query by - e.g. email, username, etc
                property: 'email'

                # optional: if you're using multiple Doctrine entity
                # managers, this option defines which one to use
                #manager_name: 'customer'

    # ...

Using a Custom Query to Load the User

The entity provider can only query from one specific field, specified by the property config key. If you want a bit more control over this - e.g. you want to find a user by email or username, you can do that by implementing UserLoaderInterface in your Doctrine repository (e.g. UserRepository):

エンティティ プロバイダーは、プロパティ構成キーで指定された 1 つの特定のフィールドからのみクエリを実行できます。これをもう少し制御したい場合 - 例えばメールまたはユーザー名でユーザーを検索したい場合は、Doctrine リポジトリ (例: UserRepository) に UserLoaderInterface を実装することで実行できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// src/Repository/UserRepository.php
namespace App\Repository;

use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;

class UserRepository extends ServiceEntityRepository implements UserLoaderInterface
{
    // ...

    public function loadUserByIdentifier(string $usernameOrEmail): ?User
    {
        $entityManager = $this->getEntityManager();

        return $entityManager->createQuery(
                'SELECT u
                FROM App\Entity\User u
                WHERE u.username = :query
                OR u.email = :query'
            )
            ->setParameter('query', $usernameOrEmail)
            ->getOneOrNullResult();
    }
}

To finish this, remove the property key from the user provider in security.yaml:

これを完了するには、ユーザー プロバイダーの insecurity.yaml からプロパティ キーを削除します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
# config/packages/security.yaml
security:
    providers:
        users:
            entity:
                class: App\Entity\User

    # ...

Now, whenever Symfony uses the user provider, the loadUserByIdentifier() method on your UserRepository will be called.

これで、Symfony がユーザー プロバイダーを使用するたびに、UserRepository の loadUserByIdentifier() メソッドが呼び出されます。

Memory User Provider

It's not recommended to use this provider in real applications because of its limitations and how difficult it is to manage users. It may be useful in application prototypes and for limited applications that don't store users in databases.

このプロバイダーを実際のアプリケーションで使用することはお勧めできません。これは、その制限と、ユーザーの管理が非常に難しいためです。これは、アプリケーションのプロトタイプや、ユーザーをデータベースに保存しない限られたアプリケーションで役立つ場合があります。

This user provider stores all user information in a configuration file, including their passwords. Make sure the passwords are hashed properly. See Password Hashing and Verification for more information.

このユーザー プロバイダーは、パスワードを含むすべてのユーザー情報を構成ファイルに格納します。パスワードが適切にハッシュされていることを確認してください。詳細については、パスワードのハッシュと検証を参照してください。

After setting up hashing, you can configure all the user information in security.yaml:

ハッシュを設定したら、security.yaml ですべてのユーザー情報を構成できます。
1
2
3
4
5
6
7
8
9
10
# config/packages/security.yaml
security:
    providers:
        backend_users:
            memory:
                users:
                    john_admin: { password: '$2y$13$jxGxc ... IuqDju', roles: ['ROLE_ADMIN'] }
                    jane_admin: { password: '$2y$13$PFi1I ... rGwXCZ', roles: ['ROLE_ADMIN', 'ROLE_SUPER_ADMIN'] }

    # ...

Caution

注意

When using a memory provider, and not the auto algorithm, you have to choose an encoding without salt (i.e. bcrypt).

自動アルゴリズムではなくメモリ プロバイダーを使用する場合は、salt を使用しないエンコーディング (つまり、bcrypt) を選択する必要があります。

Chain User Provider

This user provider combines two or more of the other providers to create a new user provider. The order in which providers are configured is important because Symfony will look for users starting from the first provider and will keep looking for in the other providers until the user is found:

このユーザー プロバイダーは、2 つ以上の他のプロバイダーを組み合わせて、新しいユーザー プロバイダーを作成します。 Symfony は最初のプロバイダーからユーザーを検索し、ユーザーが見つかるまで他のプロバイダーを検索し続けるため、プロバイダーが設定される順序は重要です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# config/packages/security.yaml
security:
    # ...
    providers:
        backend_users:
            ldap:
                # ...

        legacy_users:
            entity:
                # ...

        users:
            entity:
                # ...

        all_users:
            chain:
                providers: ['legacy_users', 'users', 'backend_users']

Creating a Custom User Provider

Most applications don't need to create a custom provider. If you store users in a database, a LDAP server or a configuration file, Symfony supports that. However, if you're loading users from a custom location (e.g. via an API or legacy database connection), you'll need to create a custom user provider.

ほとんどのアプリケーションでは、カスタム プロバイダーを作成する必要はありません。ユーザーをデータベース、LDAP サーバー、または構成ファイルに保存する場合、Symfony はそれをサポートします。ただし、カスタムの場所からユーザーをロードする場合 (たとえば、API またはレガシー データベース接続を介して)、カスタム ユーザーを作成する必要があります。プロバイダー。

First, make sure you've followed the Security Guide to create your User class.

まず、セキュリティ ガイドに従って User クラスを作成したことを確認します。

If you used the make:user command to create your User class (and you answered the questions indicating that you need a custom user provider), that command will generate a nice skeleton to get you started:

make:user コマンドを使用して User クラスを作成した場合 (そして、カスタム ユーザー プロバイダーが必要であることを示す質問に答えた場合)、そのコマンドは開始するための適切なスケルトンを生成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// src/Security/UserProvider.php
namespace App\Security;

use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class UserProvider implements UserProviderInterface, PasswordUpgraderInterface
{
    /**
     * Symfony calls this method if you use features like switch_user
     * or remember_me. If you're not using these features, you do not
     * need to implement this method.
     *
     * @throws UserNotFoundException if the user is not found
     */
    public function loadUserByIdentifier(string $identifier): UserInterface
    {
        // Load a User object from your data source or throw UserNotFoundException.
        // The $identifier argument is whatever value is being returned by the
        // getUserIdentifier() method in your User class.
        throw new \Exception('TODO: fill in loadUserByIdentifier() inside '.__FILE__);
    }

    /**
     * Refreshes the user after being reloaded from the session.
     *
     * When a user is logged in, at the beginning of each request, the
     * User object is loaded from the session and then this method is
     * called. Your job is to make sure the user's data is still fresh by,
     * for example, re-querying for fresh User data.
     *
     * If your firewall is "stateless: true" (for a pure API), this
     * method is not called.
     *
     * @return UserInterface
     */
    public function refreshUser(UserInterface $user)
    {
        if (!$user instanceof User) {
            throw new UnsupportedUserException(sprintf('Invalid user class "%s".', get_class($user)));
        }

        // Return a User object after making sure its data is "fresh".
        // Or throw a UserNotFoundException if the user no longer exists.
        throw new \Exception('TODO: fill in refreshUser() inside '.__FILE__);
    }

    /**
     * Tells Symfony to use this provider for this User class.
     */
    public function supportsClass(string $class)
    {
        return User::class === $class || is_subclass_of($class, User::class);
    }

    /**
     * Upgrades the hashed password of a user, typically for using a better hash algorithm.
     */
    public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
    {
        // TODO: when hashed passwords are in use, this method should:
        // 1. persist the new password in the user storage
        // 2. update the $user object with $user->setPassword($newHashedPassword);
    }
}

Most of the work is already done! Read the comments in the code and update the TODO sections to finish the user provider. When you're done, tell Symfony about the user provider by adding it in security.yaml:

ほとんどの作業はすでに完了しています。コード内のコメントを読み、TODO セクションを更新してユーザー プロバイダーを完成させます。完了したら、ユーザー プロバイダーを security.yaml に追加して、Symfony に伝えます。
1
2
3
4
5
6
# config/packages/security.yaml
security:
    providers:
        # the name of your user provider can be anything
        your_custom_user_provider:
            id: App\Security\UserProvider

Lastly, update the config/packages/security.yaml file to set the provider key to your_custom_user_provider in all the firewalls which will use this custom user provider.

最後に、config/packages/security.yaml ファイルを更新して、このカスタム ユーザー プロバイダーを使用するすべてのファイアウォールでプロバイダー キーを your_custom_user_provider に設定します。