Symfony redirect after login with condition on user

13,344

Solution 1

I assume you are using the Guard Authentication system. ( http://symfony.com/doc/current/security/guard_authentication.html )

Then you should have a class extending the AbstractGuardAuthenticator class.

In that class, there is a method called onAuthenticationSuccess, in here you can put some logic for redirecting the request. If you return null here, it will just continue, and use the route configured in your security.yml.

You will need to pass the @router service to the Authenticator class through dependencyInjection.

Assuming you passed the router service, your method will look something like this:

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
    /** @var User $user */
    $user = $token->getUser();

    if ($user->hasCompleteProfile() == false) {
        $url = $this->router->generate('edit_profile');

        return new RedirectResponse($url);
    }

    // Continue with default behaviour
    return null;
}

Solution 2

If all else fails (or becomes an excessive pain to deal with) you can always simply introduce an intermediary route and do your logic in there.

That is, create an action who's sole purpose is to redirect users based on whatever logic is needed, and then put that as the target path in the security.yml firewall.

security:
    firewalls:
        main:
            pattern: ^/
            anonymous: ~
            form_login: 
                login_path: login
                check_path: login
                default_target_path: login_success
                always_use_default_target_path: true
            logout:
                path: logout

Where the login would be something like:

class AuthenticationController extends Controller
{
    /**
     * @Route("/login", name="login")
     * @Route("/logout", name="logout")
     */
    public function loginAction(Request $request)
    {
        // Standard login stuff here
    }

    /**
     * @Route("/login_success", name="login_success")
     */
    public function postLoginRedirectAction()
    {
        if (/* user needs to see location A */) {
            return $this->redirectToRoute("location_a");
        } else if (/* user needs to see location B */) {
            return $this->redirectToRoute("location_b");
        } else {
            return $this->redirectToRoute("index");
        }
    }
}
Share:
13,344
Dan Chaltiel
Author by

Dan Chaltiel

Self-taught programming enthusiast, huge fan of R (tidyverse FTW!) for data analysis and data visualization. Author of the R package {crosstable}. I also love Python for ML and scripting and Java/Kotlin for Android development. Very curious about Raspberry Pi, Arduino, and Linux. Can also like a bit of PHP and Javascript on full moon nights. I am Pharm.D. and Ph.D. in epidemiology and I currently work as a biostatistician in clinical research.

Updated on August 01, 2022

Comments

  • Dan Chaltiel
    Dan Chaltiel almost 2 years

    My symfony3 login page redirects to home by default, as stated inside my security.yml file.

    However, I want it to redirect to my "Edit profile" page if the user didn't fulfil it yet. In any other form I would make this in the controller, but since there is no $form->handleRequest($user) in the login form, I don't have a $user variable to test on.

    There is a lot of SO topics about how to redirect user based on roles, and the documentation tells about redirecting from the action field of the form or within security.yml, but not any is what I'm looking for.

    How can I redirect based on a condition ?

    NB : for some reasons, I cannot use FOSUserBundle yet :-(

  • Dan Chaltiel
    Dan Chaltiel over 7 years
    Actually, I used a Simple Registration Form, and a a Traditional Login Form. I'll look into the Guard Authentication system, but the website I'm building is not due to have a rock-hard security so maybe it is an overkill...
  • Darius.V
    Darius.V almost 4 years
    What if in my case there is no extended AbstractGuardAuthenticator - I dont find such in my project? And if I dont want 2 redirects, they are slowing page down. Then only way to refactor to use AbstractGuardAuthenticator ? Or any other there is?