1. Home

Anil

< Blog />

Redirect a user when logged in FOSUserBundle

in

Using FOSUserBundle you may want to redirect the user to the homepage when they visit the login page and already logged in, this isn’t provided by default in the bundle, but it’s very easy to implement.

It involves overriding the FOSUserBundle with your own child bundle and then adding your own custom implementation of the loginAction which redirects the user as required. Let’s have a look at how to do this.


I’ll assume you’ve already setup FOSUserBundle, registered it within your AppKernel.php and configured it as stated in the Installation chapter within the documentation.

Tip

Add PATH="./bin:$PATH" to your path to run the console command from your application root without the bin/ prefix.

So bin/console becomes simply → console.


1. Create a new bundle

Create a new UserBundle to act as a child of the parent FOSUserBundle - so we can override the default controllers and templates provided by the library.

# Create our `UserBundle`
console generate:bundle --no-interaction \
--dir=src --namespace=UserBundle --bundle-name=UserBundle

# Remove skeleton demo files
rm src/UserBundle/Controller/DefaultController.php
rm src/UserBundle/Resources/config/services.yml
rm src/UserBundle/Resources/views/Default/index.html.twig

# Remove unused directories
rmdir src/UserBundle/Resources/config/
rmdir src/UserBundle/Resources/views/Default/

2. Update our bundle to specify a parent bundle

open src/UserBundle/UserBundle.php and implement the getParent() method as described by the BundleInterface to return the parent bundle’s name.

# Patch the UserBundle to implement the getParent() method

# Save the patch into a file
cat <<'-EOF' > UserBundle.patch
--- a/src/UserBundle/UserBundle.php
+++ b/src/UserBundle/UserBundle.php
@@ -6,4 +6,8 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;

 class UserBundle extends Bundle
 {
+    public function getParent()
+    {
+        return 'FOSUserBundle';
+    }
 }

-EOF

# Apply the patch and delete it (when applied successfully)
patch -p1 -l < UserBundle.patch && rm UserBundle.patch

# FOSUserBundle is now a parent of UserBundle

3. Overriding the Security Controller

touch src/UserBundle/Controller/SecurityController.php && open src/UserBundle/Controller/SecurityController.php and override the loginAction to provide our custom user role check and redirect them if already logged in.

cat <<'-EOF' > src/UserBundle/Controller/SecurityController.php
<?php

namespace UserBundle\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;

class SecurityController extends \FOS\UserBundle\Controller\SecurityController
{
    /**
     * We override loginAction to redirect the user depending on their role.
     * If they try to go to /login, they will be redirected accordingly based on their role
     *
     * @param Request $request
     * @return RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function loginAction(Request $request)
    {
        $auth_checker = $this->get('security.authorization_checker');
        $router = $this->get('router');

        // 307: Internal Redirect
        if ($auth_checker->isGranted(['ROLE_SUPER_ADMIN'])) {
            // SUPER_ADMIN roles go to the `admin_home` route
            return new RedirectResponse($router->generate('admin_home'), 307);
        }

        if ($auth_checker->isGranted('ROLE_USER')) {
            // Everyone else goes to the `home` route
            return new RedirectResponse($router->generate('home'), 307);
        }

        // Always call the parent unless you provide the ENTIRE implementation
        return parent::loginAction($request);
    }
}
-EOF

  • If a user is logged in (as ROLE_SUPER_ADMIN), they’ll be redirected to the admin_home route.
  • If a user is logged in (as ROLE_USER), they’ll be redirected to the home route.
  • If a user is not logged in, we call the parent:loginAction and use it’s implementation.

Note

You can use this same method of overriding controllers and templates to override any part of any bundle.