We will leverage on Symfony’s generators to quickly code a simple user authentication and CRUD system in less than 15 minutes.
Let’s start by creating a new Symfony project, which we will call sym_auth.
symfony new --full sym_auth
Then we will edit the .env file in the root folder, adding our database credentials.
DATABASE_URL=mysql://sym_auth:sym_auth@127.0.0.1:3306/sym_auth?serverVersion=5.7
I created my database with qdb, but you can also create yours with doctrine as below.
php bin/console doctrine:database:create
Time to create our security class.
php bin/console make:user
And add some more user attributes.
php bin/console make:entity
All done? Then, migration.
php bin/console make:migration
And migrate.
php bin/console doctrine:migrations:migrate
Now we will generate the CRUD based on the User entity.
php bin/console make:crud User
In Form/UserType we will use two new components.
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\CallbackTransformer;
And
->add('Roles', ChoiceType::class, [ 'required' => true, 'multiple' => false, 'expanded' => false, 'choices' => [ 'User' => 'ROLE_USER', 'Partner' => 'ROLE_PARTNER', 'Admin' => 'ROLE_ADMIN', ], ]) // roles field data transformer $builder->get('Roles') ->addModelTransformer(new CallbackTransformer( function ($rolesArray) { // transform the array to a string return count($rolesArray)? $rolesArray[0]: null; }, function ($rolesString) { // transform the string back to an array return [$rolesString]; } ));
Now let’s proceed with the authentication system.
php bin/console make:auth
On /src/Security/AppCustomAuthenticator.php, add the redirection route after login.
// For example : return new RedirectResponse($this->urlGenerator->generate('some_route')); // @dth: redirect the user to the user_index route return new RedirectResponse($this->urlGenerator->generate('user_index'));
On /src/Controller/UserController.php
Let’s use the interface for encrypting the password.
… use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; // @dth: to encode the pass …
And add a private attribute to hold the encoder object and a constructor to feed it
private $passwordEncoder; public function __construct(UserPasswordEncoderInterface $passwordEncoder) { $this->passwordEncoder = $passwordEncoder; }
Then, on the /new and /edit route.
// @todo: refactor $plainpwd = $user->getPassword(); $encoded = $this->passwordEncoder->encodePassword($user, $plainpwd); $user->setPassword($encoded); $user->setCreationDate(new \DateTime()); // @todo: refactor $entityManager = $this->getDoctrine()->getManager(); $plainpwd = $user->getPassword(); $encoded = $this->passwordEncoder->encodePassword($user, $plainpwd); $user->setPassword($encoded); $entityManager->persist($user); $entityManager->flush();
And finally start the server.
symfony server:start --no-tls
Hello,
I stumbled across the user edit today, and always got the error message
>>> An exception has been thrown during the rendering of a template (“Notice: Array to string conversion”). <<<
But thanks to your help it works now!
Thank you very much, that saved my day!
Many kind regards
Wolfgang