Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Custom URL redirect by role after success login on Symfony 2 using a service listener without FOSUser Bundle.
# src/Acme/DemoBundle/Security/Authentication/Handler/LoginSuccessHandler.php
<?php
namespace Acme\DemoBundle\Security\Authentication\Handler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
{
protected
$router,
$security;
public function __construct(Router $router, SecurityContext $security)
{
$this->router = $router;
$this->security = $security;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
// URL for redirect the user to where they were before the login process begun if you want.
// $referer_url = $request->headers->get('referer');
// Default target for unknown roles. Everyone else go there.
$url = 'homepage';
if($this->security->isGranted('ROLE_USER')) {
$url = 'user_homepage';
}
elseif($this->security->isGranted('ROLE_ADMIN')) {
$url = 'admin_dashboard';
}
$response = new RedirectResponse($this->router->generate($url));
return $response;
}
}
# app/config/security.yml
security:
...
firewalls:
main: # name of your firewall
form_login:
...
use_referer: false
success_handler: login_success_handler
# src/Acme/DemoBundle/Resources/config/services.yml
parameters:
acme_demo.authentication.handler.login_success_handler.class: Acme\DemoBundle\Security\Authentication\Handler\LoginSuccessHandler
services:
login_success_handler:
class: %acme_demo.authentication.handler.login_success_handler.class%
arguments: [@router, @security.context]
tags:
- { name: 'monolog.logger', channel: 'security' }
@octobel

This comment has been minimized.

Copy link

octobel commented Oct 2, 2014

Gracias! me sirvió de mucho.

@monsefoster

This comment has been minimized.

Copy link

monsefoster commented Oct 14, 2014

Muchas Gracias!

@atamashi

This comment has been minimized.

Copy link

atamashi commented Apr 20, 2015

Simple, sencillo y hermoso!

@sajjad-ardekani

This comment has been minimized.

Copy link

sajjad-ardekani commented Oct 13, 2015

Thank You

@jiri-jagos

This comment has been minimized.

Copy link

jiri-jagos commented Jan 12, 2016

You saved my night. Thank you.

@martin-damien

This comment has been minimized.

Copy link

martin-damien commented Mar 3, 2016

In the latest versions of Symfony, SecurityContext is deprecated.

You have to use:

use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;

public function __construct(Router $router, AuthorizationChecker $security)
{
    // ...
}
arguments:  ["@router", "@security.authorization_checker"]
@bipiane

This comment has been minimized.

Copy link

bipiane commented Aug 26, 2016

.../routing.yml

index:
pattern: /
defaults: { _controller: ACMEBundle:Security:index }

.../SecurityController

public function indexAction()
{
if($this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')){
return $this->redirectToRoute('foo', array());
}else{
return $this->redirectToRoute('bar', array());
}
}

@robertosanval

This comment has been minimized.

Copy link

robertosanval commented Dec 20, 2016

I'm trying to implement this solution but I've some problems with the redirection, the login form doesn't redirect after a successful login but I get the HTML code of the redirected page in my Javascript console. Any ideas?

I've done a temporary solution, returning a Json and redirecting to desired target URL by Javascript:

		$url = $this->router->generate('homepage');

		$result = array(
			'success' => true,
			'function' => 'onAuthenticationSuccess',
			'error' => false,
			'message' => 'OK',
			'url' => $url
		);

		$response = new Response(json_encode($result));
		$response->headers->set('Content-Type', 'application/json');

		return $response;

Then in Javascript: window.location.replace(data.url);

For some reason the RedirectResponse doesn't work for me :(

@hous04

This comment has been minimized.

Copy link

hous04 commented Aug 28, 2017

we need to check if isGranted as ROLE_ADMIN before , because ROLE_ADMIN has ROLE_USER also.

@Brahim1992

This comment has been minimized.

Copy link

Brahim1992 commented Mar 21, 2018

Thank you, it works like a charm.

@aceroAD

This comment has been minimized.

Copy link

aceroAD commented Mar 7, 2019

How can you make this work in symfony 4??

@erkash

This comment has been minimized.

Copy link

erkash commented Nov 21, 2019

You are the best!!! Thank you very much! On symfony 4 works fine!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.