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