DEV Community

loading...

How to automatically login customer after registration with Symfony

mis0u profile image Mickaël ・3 min read

A lot of websites allow you to be logged just after registration and I think that great for the user experience. So today I will show you how to do it with Symfony.

Basic configuration

  • Both Symfony and composer should be installed. If you use the light version of SF, make sure you have the maker bundle installed because I will use it.
  • And that's it 😊

Let's start

First I'm going to use : php bin/console make:user

//I leave User by default
 The name of the security user class (e.g. User) [User]:
 >
// Yes I want to store it
 Do you want to store user data in the database (via Doctrine)? (yes/no) [yes]:
 >
//Default value (email) is good
 Enter a property name that will be the unique "display" name for the user (e.g. email, username, uuid) [email]:
 >
// Yes I want to hash password and I let SF do it for me
 Will this app need to hash/check user passwords? Choose No if passwords are not needed or will be checked/hashed by some other system (e.g. a single sign-on server).

 Does this app need to hash/check user passwords? (yes/no) [yes]:
 >
Enter fullscreen mode Exit fullscreen mode

Our entity is now ready. Symfony just created both User Entity and UserRepository.
Now let's add the authentification by using :
php bin/console make:auth

// I choose 1 for the complete authenticator
 What style of authentication do you want? [Empty authenticator]:
  [0] Empty authenticator
  [1] Login form authenticator
 > 1
1
//I prefer to call it LoginFormAuthenticator
 The class name of the authenticator to create (e.g. AppCustomAuthenticator):
 > LoginFormAuthenticator
//It's fine for me
 Choose a name for the controller class (e.g. SecurityController) [SecurityController]:
 >
//Yes I want a logout URL
 Do you want to generate a '/logout' URL? (yes/no) [yes]:
 >
Enter fullscreen mode Exit fullscreen mode

Now we've got 4 folders in our src :
Controller

  • SecurityController.php

Entity

  • User.php

Repository

  • UserRepository.php

Security

  • LoginFormAuthenticator.php

Let's check the last one. As you can see, there are all the logics for the authentification. You can modify the parameters you want. For example here you can change the error message when the email is wrong :

 public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
        if (!$this->csrfTokenManager->isTokenValid($token)) {
            throw new InvalidCsrfTokenException();
        }

        $user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $credentials['email']]);

        if (!$user) {
            // fail authentication with a custom error
            throw new 
CustomUserMessageAuthenticationException('Email could not be found.');
        }

        return $user;
    }
Enter fullscreen mode Exit fullscreen mode

When the User is logged, I would like to redirect him to the home page. Lets pretend we've already created the HomeController with the name: "app_home".
In LoginFormAuthenticator.php there is a onAuthenticationSuccess's function. I will change the default value with a redirection to the homepage

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }
//I will delete the below line
        throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
//And replace it by this one
return new RedirectResponse($this->urlGenerator->generate('app_home'));
    }
Enter fullscreen mode Exit fullscreen mode

Great now our users will be redirect to the homepage. Let's finish it. Create a new RegisterController and the form ( I guess you know how to do it 😉).
I called my form RegisterType. So now thanks to the autowiring I am going to allow the user to be logged after registration. I will use autowiring for the Request, EntityManager,UserPasswordEncoderInterface, LoginFormAuthentificator and GuardAuthenticatorHandler :

/**
     * @Route("/register", name="app_register")
     */
    public function registration(Request $request, EntityManagerInterface $manager,UserPasswordEncoderInterface $passwordEncoder, LoginFormAuthentificator $login, GuardAuthenticatorHandler $guard)
    {
//Basic code for registration
        $user = new User();
        $form = $this->createForm(RegisterType::class, $user);
        $form->handleRequest($request);
//I always use a unmapped plainPassword for the real password
        if ($form->isSubmitted() && $form->isValid()){
            $user->setPassword($passwordEncoder->encodePassword($user, $form['plainPassword']->getData()));

            $manager->persist($user);
            $manager->flush();
//Just to be UX, I had a flash message
            $this->addFlash('success', 'The registration is successfull');
//This is how the User could be logged after the registration
//Guard handle it
//'main' is your main Firewall. You can check it in config/packages/security.yaml
            return $guard->authenticateUserAndHandleSuccess($user,$request,$login,'main');
        }

        return $this->render('security/registration.html.twig', ['form' => $form->createView(),]);
    }
Enter fullscreen mode Exit fullscreen mode

This is how to do it with SF, I hope it's gonna help you in your future registration !

That's all folks 😁

Discussion (2)

pic
Editor guide
Collapse
rogluee profile image
John Doe

Don't use entities in form!

Collapse
mis0u profile image
Mickaël Author

You mean $user = new User () ?