Search code examples
symfonypasswords

Add special characters and number in password symfony


For my project, I have to create Users and I would like to change the properties of the password. Symfony automaticcaly define 6 characters for it, but i would like to add special characters and number in it. For the length i'm fine, but for the rest i don't find the answers.

Here is my form

->add('plainPassword', PasswordType::class, [
                // instead of being set onto the object directly,
                // this is read and encoded in the controller
                'mapped' => false,
                'attr' => ['autocomplete' => 'new-password'],
                'constraints' => [
                    new NotBlank([
                        'message' => 'Please enter a password',
                    ]),
                    new Length([
                        'min' => 6,
                        'minMessage' => 'Your password should be at least {{ limit }} characters',
                        // max length allowed by Symfony for security reasons
                        'max' => 4096,
                    ]),
                ],
            ])

Do you know if I change the properties in my form it will be enough?

Thanks for your help.


Solution

  • Take a look at Compound constraint

    So basically you would create your own "rules-set". In this case, for passwords.

    In order to have at least one number (digit) or/and one special-char, you could use Regex Constraints. To be more precise - two of them:

    • to match at least one digit
    • to match at least one special char
    // src/Validator/Constraints/MyPasswordRequirements.php
    
    use Symfony\Component\Validator\Constraints\Compound;
    use Symfony\Component\Validator\Constraints as Assert;
    
    class MyPasswordRequirements extends Compound {
    
        protected function getConstraints(array $options): array
        {
            return [
                new Assert\NotBlank(),
                new Assert\Type('string'),
                new Assert\Length(['min' => 6]),
                //regex -> to have at elast one digit
                new Assert\Regex([
                    'pattern' => '/\d+/i', 
                ]),
                //regex -> to have at elast one special char from the list
                //note: list of special-char is [#?!@$%^&*-]. Adjust to suite your needs
                new Assert\Regex([
                    'pattern' => '/[#?!@$%^&*-]+/i', 
                ]),
            ];
        }
    }
    

    and then in your form just use this one MyPasswordRequirements constraint

    
    ->add('plainPassword', PasswordType::class, [
        'mapped' => false,
        'attr' => ['autocomplete' => 'new-password'],
        'constraints' => [
            new MyPasswordRequirements()
        ],
        // validation error message 
        'invalid_message' => 'Password requirements are not fulfilled'
    ])
    

    P.S. I intentionally split reg-ex in two, just for better understanding and demonstration. I can combine them into one, and perhaps add further restrictions. Take as look at Regex strong password the special characters