Skip to content

Instantly share code, notes, and snippets.

@inoryy
Forked from weaverryan/gist:1540293
Created December 30, 2011 15:29
Show Gist options
  • Save inoryy/1540318 to your computer and use it in GitHub Desktop.
Save inoryy/1540318 to your computer and use it in GitHub Desktop.

Redirecting to last visited page after registration.

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

Normally our user will be redirected to login page and if they already have an account, they can login and get redirected to the page they were looking for. This is possible thanks to Symfony2 Authentication listener where a session parameter is set to what the last page was before firewall was hit and then purged the moment you login.

But what if they're a new user? After clicking another link to register and filling out the form, how can you redirect them back to the page they're actually looking for?

Well, let's solve this little problem by exploiting the same feature that is used for login form. All you need to do is let symfony do its magic - redirect user to a login page from your private page and if he succesfully registers re-use that session parameter:

// ...

use Symfony\Component\Request\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\UserInterface;

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);

            // try to redirect to the last page, or fallback to the homepage
            if ($this->container->get('session')->has('_security.target_path')) {
                $url = $this->container->get('session')->get('_security.target_path');
                $this->container->get('session')->remove('_security.target_path');
            } 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 your users can access a protected page, register, and get redirected right back to that 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 [Symfony2 Authentication Listener] (https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php) . More specifically, [determineTargetUrl] (https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php#L259) method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment