简体   繁体   中英

How does symfony2 redirect to requested page after login

Say my route /booking/(.*) is protected by a firewall configuration in security.yml and it requires " ROLE_USER ", when user tries to access any route that is preceded by " /booking/ " the app redirects the user to login page for authentication.

So my question is, after user provides his credentials and gets authenticated, how is Symfony 2 able to redirect the user back to the page/route the user had requested for OR where does Symfony 2 store that route does it store it in some session or some where else.

Can we access it and how?

This is possible and you can access the referring link (that is used if use_referer is set to true ) in the session.

For instance, if you have a success_handler service on your form_login (in your firewall configuration) that redirects users based on some criteria (commonly roles) but you wanted to redirect the user to the referrer link if it was set you could access the referrer link like so:

$key = '_security.main.target_path'; #where "main" is your firewall name

//check if the referrer session key has been set 
if ($this->container->get('session')->has($key)) {
    //set the url based on the link they were trying to access before being authenticated
    $url = $this->container->get('session')->get($key);

    //remove the session key
    $this->container->get('session')->remove($key);
}
//if the referrer key was never set, redirect to a default route
else{
    $url = $this->router->generate('member_home');
}

return new RedirectResponse($url); 

Using the header to get the referrer (ie $request->headers->get('referer') ) will not work in this case because it will always return the login link.

Thanks to Roman Marintsenko & Ryan Weaver for this blog

Carrie Kendall's solution worked, thanks!

Here is full implementation in Symfony:

services.yml:

login_handler:
    class: Project\BaseBundle\Service\loginHandler
    arguments: ['@router', '@doctrine.orm.entity_manager', '@service_container']

and in Project\\BaseBundle\\Service\\loginHandler:

namespace Project\BaseBundle\Service;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Routing\RouterInterface;
use Doctrine\ORM\EntityManager;


class loginHandler implements AuthenticationSuccessHandlerInterface {

    private $router;
    private $container;
    private static $key;

    public function __construct(RouterInterface $router, EntityManager $em, $container) {

        self::$key = '_security.secured_area.target_path';

        $this->router = $router;
        $this->em = $em;
        $this->session = $container->get('session');

    }

    public function onAuthenticationSuccess( Request $request, TokenInterface $token ) {

        $user_entity = $token->getUser();

        if( !$user_entity->getChangePassword() ) {

            $route = $this->router->generate('BaseBundle_home_page');

        } else {

            $this->session->getFlashBag()->add('error', 'Your password must be changed now');

            $route = $this->router->generate('BaseBundle_account_page');

        }

        //check if the referer session key has been set
        if ($this->session->has( self::$key )) {

            //set the url based on the link they were trying to access before being authenticated
            $route = $this->session->get( self::$key );

            //remove the session key
            $this->session->remove( self::$key );
            //if the referer key was never set, redirect to a default route

        } else{

            $url = $this->generateUrl('BaseBundle_home_page');

            return new RedirectResponse($route);

        }

        return new RedirectResponse($route);

    }
}

I had this problem too. I used security.yml and in the registration action used:

$redirectUrl = $request->getSession()->get('_security.account.target_path');

enjoy.

Symfony uses the HTTP Referer header to redirect a user back to the page they came from .. ie the referrer

You can set this using the security configuration use_referer: true in the security.yml, details here

You can access the referer header from a controller using using the following :

$referer = $request->headers->get('referer');

Note the header is miss-spelt, its referer (one r)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM