Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Configuring the Encoder in security.yml

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

Let's set some plain passwords! Where? In our fixtures! Open up fixtures.yml and scroll down. In theory, all we need to do is set the plainPassword property. The rest should happen auto-magically.

Add plainPassword: and we'll keep with iliketurtles, because I've gotten good at typing that. And turtles are cool:

... lines 1 - 22
AppBundle\Entity\User:
user_{1..10}:
... line 25
plainPassword: iliketurtles

Change over to your terminal and load your fixtures:

./bin/console doctrine:fixtures:load

Explosion!

No encoder has been configured for AppBundle\Entity\User

This is basically Symfony's way of saying:

Ryan, you didn't tell me how you want to encode the passwords. I can't read your mind - I'm just a PHP framework.

Remember how I kept saying we would encrypt the passwords with bcrypt? Do you remember actually configuring that anywhere? Nope! We need to do that.

Open security.yml. Add an encoders key, then AppBundle\Entity\User: bcrypt:

... lines 1 - 2
security:
encoders:
AppBundle\Entity\User: bcrypt
... lines 6 - 33

If you want, you can configure a few other options, but this is good enough.

Now Symfony knows how to encrypt our passwords. Try the fixtures again:

./bin/console doctrine:fixtures:load

No errors! So, that probably worked. Let's use it!

Checking the Encoded Password

In LoginFormAuthenticator, we can finally add some real password checking! How? By using that same UserPasswordEncoder object.

Head back up to __construct and add a new UserPasswordEncoder argument. I'll use my Option+Enter shortcut to setup that property for me:

... lines 1 - 10
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
... lines 12 - 15
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
... lines 18 - 20
private $passwordEncoder;
public function __construct(FormFactoryInterface $formFactory, EntityManager $em, RouterInterface $router, UserPasswordEncoder $passwordEncoder)
{
... lines 25 - 27
$this->passwordEncoder = $passwordEncoder;
}
... lines 30 - 78
}

And because we're using autowiring for this service, we don't need to change anything in services.yml.

Now, in checkCredentials(), replace the if statement with if ($this->passwordEncoder->isPasswordValid()) and pass that the User object and the plain-text password:

... lines 1 - 15
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
... lines 18 - 58
public function checkCredentials($credentials, UserInterface $user)
{
... lines 61 - 62
if ($this->passwordEncoder->isPasswordValid($user, $password)) {
return true;
}
... lines 66 - 67
}
... lines 69 - 78
}

That'll take care of securely checking things.

Let's try it out: head to /login. Use weaverryan+1@gmail.com and iliketurtles. We're in! Password system check.

Ok team, that's it for authentication. You can build your authenticator to behave however you want, and you can even have multiple authenticators. Oh, and if you do want to use any of the built-in authentication systems, like the form_login key I mentioned earlier - that's totally fine. Guard authentication takes more work, but has more flexibility. If you want another example, we created a cool JSON web token authenticator in our Symfony REST series.

Now, let's start locking down the system.

Leave a comment!

5
Login or Register to join the conversation
Juan carlos Avatar
Juan carlos Avatar Juan carlos | posted 5 years ago

Hi guys, there is an '+' missing on line src/AppBundle/DataFixtures/ORM/fixtures.yml:25. Excelento work!

Reply

Hey Juan carlos

I just downloaded the course code and I can see the "+" on that line (and it is on the code blocks as well). Could you double check it?

Cheers!

Reply
Juan carlos Avatar

May not be in the code, but in your web.

Reply
Sara Avatar

If you are having issues with your event listener picking up the hash password listener in 3.4

Your service yml should look like this so that the fixtures generate the hashed passwords.

app.doctrine.hash_password_listener:
class: AppBundle\Doctrine\HashPasswordListener
autowire: true
tags:
- { name: doctrine.event_listener, event: prePersist, lazy: true }

Reply

Hey Sara!

Your code WILL totally work. But, the code in the tutorial should work too. Does your HashPasswordListener implement the EventSubscriber interface? Basically, there are 2 valid ways to create "listeners" - the tutorial shows the "subscriber" method. You are (actually, perfectly) showing the other method or configuring it.

Oh, and the lazy: true part is not needed, but a nice idea - it gives you a small performance boost when Doctrine is working, but your listener is not actually needed. Good find ;). In Symfony 4.2, that config will be ON by default... because it's just THAT awesome :p.

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.1.*", // v3.1.4
        "doctrine/orm": "^2.5", // v2.7.2
        "doctrine/doctrine-bundle": "^1.6", // 1.6.4
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
        "symfony/swiftmailer-bundle": "^2.3", // v2.3.11
        "symfony/monolog-bundle": "^2.8", // 2.11.1
        "symfony/polyfill-apcu": "^1.0", // v1.2.0
        "sensio/distribution-bundle": "^5.0", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "knplabs/knp-markdown-bundle": "^1.4", // 1.4.2
        "doctrine/doctrine-migrations-bundle": "^1.1" // 1.1.1
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.0.7
        "symfony/phpunit-bridge": "^3.0", // v3.1.3
        "nelmio/alice": "^2.1", // 2.1.4
        "doctrine/doctrine-fixtures-bundle": "^2.3" // 2.3.0
    }
}
userVoice