Skip to content
Advertisement

Manually hash (i.e. encode) a string value in Symfony 3.4

Is there a way in Symfony 3.4 to use the password encoder without an entity that implements UserInterface?


Details

I want to hash a random string value in Symfony 3.4. I can always use password_hash, but I’m trying to do this the Symfony way and take advantage of the framework. Here’s where I’m getting stuck:

The Symfony Documentation has an example, but it’s using the UserPasswordEncoder which assumes you have an entity implementing UserInterface to pass as the first argument to encodePassword($user, $plainPassword).

In this case, I don’t have a user entity because I’m generating a token for an email link. I do have an entity, but it feels wrong to have it implement UserInterface when it’s not a user.

I dug into the code for UserPasswordEncoder and thought I could just inject the PasswordEncoderInterface which has a generic encodePassword($plainPassword, $salt) method, but I get this exception when I try to autowire it:

Cannot autowire service "SriBundleServicePubMatchPublicationMatchLogService":
argument "$passwordEncoder" of method "__construct()" references interface
"SymfonyComponentSecurityCoreEncoderPasswordEncoderInterface" but no such service exists.
It cannot be auto-registered because it is from a different root namespace.

It seems Symfony doesn’t have a default service that implements PasswordEncoder and can be autowired. Am I missing something here, or does Symfony assume you only want to hash passwords for user entities and doesn’t support encoding a hash for a random string value without passing in an associated user?

Advertisement

Answer

There is no PasswordEncoderInterface implementation service defined by default in Symfony. They are used internally with UserPasswordEncoderInterface.

I found this thanks to the debug:container command.

But you can easily define them yourself! Here is an example using SodiumPasswordEncoder in config/services.yaml file:

services:

    # ... Your other definitions

    # Define an alias to allow autowiring on the interface
    SymfonyComponentSecurityCoreEncoderPasswordEncoderInterface: '@password_encoder.sodium'

    # Define the concrete service
    # You can add the arguments entry if needed
    password_encoder.sodium:
        class: SymfonyComponentSecurityCoreEncoderSodiumPasswordEncoder
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement