symfony/password-hasher
Symfony PasswordHasher provides secure password hashing and verification utilities. Configure multiple algorithms via PasswordHasherFactory (bcrypt, sodium/Argon2, etc.), hash plain passwords, verify hashes, and support upgrades with modern best practices.
Architecture fit:
The symfony/password-hasher package excels in security-first architectures where compliance (NIST SP 800-63B, OWASP, GDPR) and algorithm flexibility are critical. Its factory-based design enables multi-algorithm support (Argon2, bcrypt, sodium) and auto-migration, which aligns with Laravel’s need for secure authentication but requires a custom integration layer due to Laravel’s facade-centric Hash system. The package’s declarative configuration (e.g., PasswordHasherFactory) contrasts with Laravel’s implicit hashing, necessitating an adapter to expose Symfony’s features (e.g., needsRehash()) through Laravel’s HashContract. For projects with legacy hashes, tiered security, or compliance mandates, this is a high-value fit; for simple bcrypt use cases, the overhead may not be justified.
Technical risk:
Key questions:
spatie/laravel-password-hasher)?symfony/security-bundle)?auto algorithm) or manually?Stack fit:
The package is PHP/Laravel-compatible but requires intentional adaptation due to Laravel’s facade-based Hash system versus Symfony’s factory pattern. Key compatibility considerations:
Hash facade (Hash::make(), Hash::check()) must be wrapped or extended to use PasswordHasherFactory.HashServiceProvider) to replace or extend the default Hash implementation.bcrypt must be aliased to Symfony’s bcrypt hasher, while adding support for argon2id, sodium, etc.argon2id$v=19$m=65536...) may require database schema updates or a polyfill layer for legacy systems.Migration path:
SymfonyHashAdapter implementing HashContract to bridge PasswordHasherFactory and Laravel’s Hash facade.class SymfonyHashAdapter implements HashContract {
public function make($value, array $options = []): string {
return $this->factory->getPasswordHasher($options['algorithm'] ?? 'auto')->hash($value);
}
public function check($value, $hashedValue, array $options = []): bool {
return $this->factory->getPasswordHasher($options['algorithm'] ?? 'auto')->verify($hashedValue, $value);
}
public function needsRehash($hashedValue, array $options = []): bool {
return $this->factory->getPasswordHasher($options['algorithm'] ?? 'auto')->isPasswordTooOld($hashedValue);
}
}
config/app.php or a custom HashServiceProvider.config/hash.php:
'algorithms' => [
'default' => 'bcrypt',
'admin' => ['algorithm' => 'argon2id', 'memory_cost' => 65536],
],
users.password column to VARCHAR(255) if using Argon2.hash_algorithm column (optional) to track algorithm per user.Hash::make() with the adapter for new users (using auto algorithm).needsRehash()).Compatibility:
symfony/password-hasher (no symfony/security-bundle).laravel/sanctum or spatie/laravel-permission, which may assume Laravel’s default Hash behavior.Sequencing:
Hash facade in authentication logic (e.g., LoginController, RegisterController).needsRehash() calls to track migration progress.Maintenance:
symfony/password-hasher proactively.Support:
Hash::debug($hashedValue) method to inspect hash metadata (algorithm, parameters).User hash upgraded from bcrypt to argon2id).memory_cost).Scaling:
How can I help you explore Laravel packages today?