Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect if the user is logged in

Tags:

symfony

I am building a web application with Symfony 2, using the FOSUserBundle bundle.
Users create an account, login and start using the application.

What I want to achieve now is to have the user redirected to their account from any page they may be at if they are logged in.
This includes:

  • if they get back to the login page
  • if they get back to the registration page
  • if they go to the homepage of the website
  • once they confirm their email
  • once they reset their password

Basically the code would be something like this:

$container = $this->container;
$accountRouteName = "DanyukiWebappBundle_account";
if( $container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){
    // authenticated (NON anonymous)
    $routeName = $container->get('request')->get('_route');
    if ($routeName != $accountRouteName) {
        return $this->redirect($this->generateUrl($accountRouteName));
    }
}

The problem is I don't know where that code should go.
It should be executed for any request. In Symfony 1 I would have used a filter.

like image 634
Dan Avatar asked May 07 '12 19:05

Dan


People also ask

How do I redirect a user after login?

To do this, go to Settings » Confirmation from the left column, then select 'Go to URL' redirect as your confirmation type. Then, you can enter the URL where your users will be redirected. Your login form is now ready. Make sure you click the 'Save' button before closing the form builder interface.

How do I redirect to login page if user is not logged in WordPress?

function login_redirect() { // Current Page global $pagenow; // Check to see if user in not logged in and not on the login page if(! is_user_logged_in() && $pagenow != 'wp-login. php') // If user is, Redirect to Login form.

What is a login callback?

public interface LogInCallback. A LogInCallback is used to run code after logging in a user. The easiest way to use a LogInCallback is through an anonymous inner class. Override the done function to specify what the callback should do after the login is complete.


2 Answers

I found the solution myself:

<?php

namespace Danyuki\UserBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;

class LoggedInUserListener
{
    private $router;
    private $container;

    public function __construct($router, $container)
    {
        $this->router = $router;
        $this->container = $container;
    }    

    public function onKernelRequest(GetResponseEvent $event)
    {
        $container = $this->container;
        $accountRouteName = "DanyukiWebappBundle_account";
        if( $container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){
            // authenticated (NON anonymous)
            $routeName = $container->get('request')->get('_route');
            if ($routeName != $accountRouteName) {
                $url = $this->router->generate($accountRouteName);
                $event->setResponse(new RedirectResponse($url));
            }
        }
    }
}

And then, in the services.yml file of my bundle:

services:
    kernel.listener.logged_in_user_listener:
            class: Danyuki\UserBundle\Listener\LoggedInUserListener
            tags:
                - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
            arguments: [ @router, @service_container ]  
like image 143
Dan Avatar answered Sep 28 '22 09:09

Dan


You can also do this solution if you want to just check once:

There is an event triggered each time there's a successful login being done. The event is named:

security.interactive_login

In order to subscribe to this event, you have to create a service container with your created class let's say "LoginListener.php" and inject the tag "kernel.even_listener" with the event "security.interactive_login":

<service id="mylogin.success.listener" class="path\to\class\LoginListener">
   <tag name="kernel.event_listener" event="security.interactive_login" method="onLoginSuccess" />
</service>

in LoginListener:

use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

public function onLoginSuccess(InteractiveLoginEvent $event) {
   if ($this->_security->isGranted('IS_AUTHENTICATED_FULLY')) {
      //your code here...
   }
}

you can also add other dependencies and inject it to the constructor, in my case I had to inject security, session and container:

public function __construct(SecurityContext $security, Session $session,            ContainerInterface $container) {

}
like image 38
Francis Avatar answered Sep 28 '22 09:09

Francis