Symfony redirect to referring page after registration

633 Views Asked by At

In my Symfony 5 project, I have a payment page restricted to members only.

 /**
 * @Route("/membership_payment/{id}", name="membership_payment")
 * @IsGranted("ROLE_MEMBER")
 */

If not signed in, this presents users with the choice to login or register. If they log in, they are then redirected back to the correct page (/membership_payment/{id}), however if they register, they are correctly registered and automatically logged in but are returned to the /register page and not the /membership_payment/{id} page.

I have followed the instructions on SymfonyCasts and cannot see what I have done wrong.

My registration controller:

    /**
     * @Route("/register", name="app_register")
     *
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $authenticator) :Response
    {
        $user = new User();
        $form = $this->createForm(RegistrationFormType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $entityManager = $this->getDoctrine()->getManager();

            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    $form->get('plainPassword')->getData()
                )
            );
            $user->setRoles(['ROLE_MEMBER']);
            $user->setMembership($entityManager->getRepository(Membership::class)->find(1));
            $entityManager->persist($user);
            $entityManager->flush();
            
             return $guardHandler->authenticateUserAndHandleSuccess(
                $user,
                $request,
                $authenticator,
                'main' // firewall name in security.yaml
            );
        }

        return $this->render(
            'registration/register.html.twig',
            [
                'registrationForm' => $form->createView(),
            ]
        );
    }

security.yaml

security:
  enable_authenticator_manager: true
  encoders:
    App\Entity\User:
      algorithm: auto

  providers:
    # used to reload user from session & other features (e.g. switch_user)
    app_user_provider:
      entity:
        class: App\Entity\User
        property: email
  firewalls:
    dev:
      pattern: ^/(_(profiler|wdt)|css|images|js)/
      security: false
    main:
      lazy: true
      provider: app_user_provider
      guard:
        authenticators:
          - App\Security\LoginFormAuthenticator
      logout:
        path: app_logout
        target: home
      remember_me:
        secret: '%kernel.secret%'
        secure: true

In LoginFormAuthenticator

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) :RedirectResponse
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->urlGenerator->generate('home'));
    }
1

There are 1 best solutions below

0
On

I had a brain fart and figured it out myself already.

The register route was not included in my RequestSubscriber exclusions...

class RequestSubscriber implements EventSubscriberInterface
{

    use TargetPathTrait;

    private SessionInterface $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public function onKernelRequest(RequestEvent $event) :void
    {
        $request = $event->getRequest();
        if (
            !$event->isMasterRequest()
            || $request->isXmlHttpRequest()
            || 'app_login' === $request->attributes->get('_route')
            || 'app_register' === $request->attributes->get('_route') // I needed to add this
        ) {
            return;
        }

        $this->saveTargetPath($this->session, 'main', $request->getUri());
    }

    public static function getSubscribedEvents() :array
    {
        return [
            KernelEvents::REQUEST => ['onKernelRequest'],
        ];
    }
}