Redirecting after Registration in Symfony2

Published on

Jan 12, 2012

how2tips

Jan 13, 2012 − Ever wonder how to redirect a new user back to her last visited page after registration? We'll show you how easy it is by taking advantage of some security iternals.

Imagine this scenario: A user on your site finds an awesome link, but it's only open to registered users.

Normally the user would be redirected to the login page and if she already has an account, she can login and be redirected to the page she was looking for. This is possible thanks to the Symfony2 Authentication listener. Behind the scenes, a session parameter is set to the page user was trying to visit and then used the moment she logs in.

But what if she is a new user? After clicking another link to register and filling out the form, how can you redirect her back to the page she was actually looking for?

Let's solve this little problem by exploiting the redirect feature used by the login system. To start, just let Symfony do its magic - redirecting the user to a login page from your private page. After a successful registration, just re-use that session parameter:

// ...

use SymfonyComponentRequestRequest;
use SymfonyBundleFrameworkBundleControllerController;
use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken;
use SymfonyComponentSecurityCoreUserUserInterface;

class RegistrationController extends Controller
{
    public function registerAction(Request $request)
    {
        $form = $this->createForm(new SomeRegistrationForm());
        $form->bindRequest($request);

        if ($form->isValid()) {
            // do something awesome, like saving the User created by your registration form
            $user = $form->getData();

            // authenticate your user right now
            $this->authenticateUser($user);

            // if you're using Symfony 2.0
            $key = '_security.target_path';

            // if you're using Symfony 2.1 or greater
            // where "main" is the name of your firewall in security.yml
            $key = '_security.main.target_path';

            // try to redirect to the last page, or fallback to the homepage
            if ($this->container->get('session')->has($key)) {
                $url = $this->container->get('session')->get($key)
                $this->container->get('session')->remove($key);
            } else {
                $url = $this->container->get('router')->generate('homepage');
            }

            return new RedirectResponse($url);
        }

        // .. re-render the form on error
    }

    private function authenticateUser(UserInterface $user)
    {
        $providerKey = 'main'; // your firewall name
        $token = new UsernamePasswordToken($user, null, $providerKey, $user->getRoles());

        $this->container->get('security.context')->setToken($token);
    }
}

And that's it! Now from a protected page, your users can register, and get redirected right back to that protected page. One key to the process is being able to authenticate your user manually on login. The code in authenticateUser() method does just that. Have fun!

P.S. If you're curious where the magic is actually done, check out the Symfony2 Authentication Listener. More specifically, the determineTargetUrl method.

Written by

KNP Labs
KNP Labs

Comments