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 "SriBundle\Service\PubMatch\PublicationMatchLogService":
argument "$passwordEncoder" of method "__construct()" references interface
"Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface" 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?
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
Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface: '@password_encoder.sodium'
# Define the concrete service
# You can add the arguments entry if needed
password_encoder.sodium:
class: Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder