rollerworks/password-strength-validator
Symfony Validator password strength constraints with two approaches: validate by strength levels (weak/medium/strong) or by explicit requirements (letters, mixed case, numbers, special chars). PHP 8.4+ and Symfony 7.4+.
composer require rollerworks/password-strength-validator
// config/services.yaml
Symfony\Component\Validator\ValidatorBuilder:
methods:
addValidatorService: ['@rollerworks.password_strength_validator']
use Rollerworks\PasswordStrengthValidator\Constraints as PasswordAssert;
class UserType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('password', TextType::class, [
'constraints' => [
new PasswordAssert\ValidPassword([
'message' => 'Password is too weak',
'minStrength' => 'medium'
])
]
]);
}
}
weak, medium, strong, very_strong (configurable in config/packages/rollerworks_password_strength.yaml).PasswordAssert\PasswordStrength for granular control.ValidatorInterface).Form Validation:
// In a controller or form type
$validator = $this->get('validator');
$errors = $validator->validate($user, [
new PasswordAssert\ValidPassword(['minStrength' => 'strong'])
]);
API/Command Validation:
use Symfony\Component\Validator\Validator\ValidatorInterface;
class RegisterUserCommand {
public function __construct(
private ValidatorInterface $validator
) {}
public function execute(string $password) {
$errors = $this->validator->validate($password, [
new PasswordAssert\PasswordStrength([
'minLength' => 12,
'maxLength' => 32,
'requirements' => [
'letters' => true,
'numbers' => true,
'specialChars' => true,
]
])
]);
// Handle errors...
}
}
Dynamic Strength Levels:
// Adjust strength based on user role (e.g., admin vs. regular)
$constraint = new PasswordAssert\ValidPassword([
'minStrength' => $user->isAdmin() ? 'very_strong' : 'medium'
]);
new PasswordAssert\ValidPassword([
'minStrength' => 'medium',
'message' => '{{ value }} is not strong enough.',
]),
new NotBlank(),
new Length(['min' => 8]),
# config/packages/rollerworks_password_strength.yaml
rollerworks_password_strength:
strength_levels:
weak:
minLength: 6
requirements:
letters: true
medium:
minLength: 10
requirements:
letters: true
numbers: true
use Rollerworks\PasswordStrengthValidator\Constraints as PasswordAssert;
class RegisterDto {
#[PasswordAssert\ValidPassword(['minStrength' => 'strong'])]
public string $password;
}
Missing NotBlank:
The validator does not enforce non-empty passwords. Always pair with:
new NotBlank(),
new PasswordAssert\ValidPassword(...),
Symptom: Empty passwords pass validation silently.
Case Sensitivity in Requirements:
specialChars checks for non-alphanumeric characters (e.g., !@#).letters is case-insensitive by default (use uppercaseLetters/lowercaseLetters for stricter checks).Config Overrides:
config/packages/... override defaults but do not merge with them. Test thoroughly after changes.Performance:
Enable Symfony’s validation debug mode:
# config/packages/validator.yaml
framework:
validator:
debug: true
Output: Detailed error messages with failed rules.
Inspect strength levels:
$validator = new \Rollerworks\PasswordStrengthValidator\PasswordStrengthValidator();
$score = $validator->getPasswordStrengthScore('P@ssw0rd');
// Returns an array with scores for each requirement.
Custom Validators:
Extend \Rollerworks\PasswordStrengthValidator\PasswordStrengthValidator to add logic (e.g., dictionary checks):
use Rollerworks\PasswordStrengthValidator\PasswordStrengthValidator as BaseValidator;
class CustomPasswordValidator extends BaseValidator {
public function validate($value, Constraint $constraint) {
if ($this->isCommonPassword($value)) {
$this->context->buildViolation($constraint->commonPasswordMessage)
->addViolation();
}
parent::validate($value, $constraint);
}
}
Register it as a service alias.
Override Strength Calculations:
Replace the default PasswordStrengthValidator with a decorated version:
services:
rollerworks.password_strength_validator:
class: App\Validator\CustomPasswordStrengthValidator
decorates: 'rollerworks.password_strength_validator'
Localization: Customize error messages per locale by overriding the translator or using Symfony’s validation groups:
new PasswordAssert\ValidPassword([
'message' => 'Le mot de passe est trop faible.',
'groups' => ['fr']
]);
minStrength with incremental levels (e.g., weak → medium) to guide users toward stronger passwords.if ($errors->count()) {
$this->logger->warning('Password validation failed', [
'errors' => $errors->getIterator(),
'user_id' => $user->id
]);
}
How can I help you explore Laravel packages today?