You are browsing the documentation for Symfony 4.1 which is not maintained anymore.
Consider upgrading your projects to Symfony 5.2.
How to Load Security Users from the Database (the Entity Provider)
How to Load Security Users from the Database (the Entity Provider)¶
Each User class in your app will usually need its own user provider.
If you’re loading users from the database, you can use the built-in entity
provider:
- YAML
1 2 3 4 5 6 7 8 9 10 11 12 13
# config/packages/security.yaml # ... providers: our_db_provider: entity: class: App\Entity\User # the property to query by - e.g. username, email, etc property: username # if you're using multiple entity managers # manager_name: customer # ...
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
<!-- config/packages/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> <provider name="our_db_provider"> <!-- if you're using multiple entity managers, add: manager-name="customer" --> <entity class="App\Entity\User" property="username" /> </provider> <!-- ... --> </config> </srv:container>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// config/packages/security.php use App\Entity\User; $container->loadFromExtension('security', [ 'providers' => [ 'our_db_provider' => [ 'entity' => [ 'class' => User::class, 'property' => 'username', ], ], ], // ... ]);
The providers
section creates a “user provider” called our_db_provider
that
knows to query from your App\Entity\User
entity by the username
property.
The name our_db_provider
isn’t important: it’s not used, unless you have multiple
user providers and need to specify which user provider to use via the provider
key under your firewall.
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 making your
UserRepository
implement a special
Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface
. This
interface only requires one method: loadUserByUsername($username)
:
// src/Repository/UserRepository.php
namespace App\Repository;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository implements UserLoaderInterface
{
public function loadUserByUsername($username)
{
return $this->createQueryBuilder('u')
->where('u.username = :username OR u.email = :email')
->setParameter('username', $username)
->setParameter('email', $username)
->getQuery()
->getOneOrNullResult();
}
}
To finish this, remove the property
key from the user provider in
security.yaml
:
- YAML
1 2 3 4 5 6 7 8
# config/packages/security.yaml security: # ... providers: our_db_provider: entity: class: App\Entity\User
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<!-- config/packages/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> <!-- ... --> <provider name="our_db_provider"> <entity class="App\Entity\User" /> </provider> </config> </srv:container>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// config/packages/security.php use App\Entity\User; $container->loadFromExtension('security', [ // ... 'providers' => [ 'our_db_provider' => [ 'entity' => [ 'class' => User::class, ], ], ], ]);
This tells Symfony to not query automatically for the User. Instead, when needed
(e.g. because switch_user
, remember_me
or some other security feature is
activated), the loadUserByUsername()
method on UserRepository
will be called.
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.