Skip to main content

Hashing password in an Event Engine application

This blog post was published more than one year ago and might be outdated!
· 3 min read
Stephan Hochdörfer

For a few projects we make use of the Event Engine by prooph software which is a biased - in a good way(tm) - way of quickly building event sourced applications. While building a user registration context, I was stuck a bit how and where to properly hash the password for the user. I could have done it in the init() method of the command, that way I would have made sure that the cleartext password is not "visible" anywhere in the application code. In the end, I decided to make use of a provider class. The return value of the provider will be passed to the specified aggregate method and allows me to pass it to the respective event.

First, I created a marker interface for the commands to make sure that only commands that implement the interface can be passed to the provider class:

interface HasUnhashedPassword
* @return UnhashedPassword
public function password(): ?UnhashedPassword;

As you can see, the password() method returns an UnhashedPassword value object (or null in case no password was provided). Besides having an UnhashedPassword value object, I have also created a HashedPassword value object that gets returned by the provider class. Having a clear distinction between unhashed and hashed passwords makes sense and helps to communicate the intent of method parameters or return values better.

As the next step, a Password Hasher is needed which contains the logic to turn an unhashed password into a HashedPassword. The concrete implementation does not matter now, let's have a look at the interface:

interface PasswordHasher
/** Encrypts the given password */
public function createHash(UnhashedPassword $password): HashedPassword;

/** Verifies the given plain text password against the hashed one */
public function verify(UnhashedPassword $password,
HashedPassword $hashedPassword): bool;

Password hasher instances get injected into the HashedPasswordProvider - the provider class defined by the Event Engine:

final class HashedPasswordProvider
/** @var PasswordHasher */
private $passwordHasherer;

public function __construct(PasswordHasher $passwordHasherer)
$this->passwordHasherer = $passwordHasherer;

public function __invoke(HasUnhashedPassword $command): HashedPassword
return HashedPassword::createFromUnhashedPasswordWithHasher(
$command->password(), $this->passwordHasherer

To register the provider class add a provideContext() method call to the $eventEngine configuration and pass the class name of the HashedPasswordProvider implementation. The Event Engine will take care of executing the provider class and passing the return value to the aggregate:

->handle([Attendee::class, 'register'])
->apply([Attendee::class, 'whenRegistered'])

The aggregate implementation looks like this:

final class Attendee
public static function register(RegisterAttendee $command,
HashedPassword $hashedPassword): Generator
$attendee = $command->toArray();
$attendee[Payload::ATTENDEE_PASSWORD] = $hashedPassword->toString();
yield Registered::fromArray($attendee);

This way the aggregate has access to the command object as well as the hashed password and can do whatever needs to be done.