FloatFlower.Huang
FloatFlower.Huang

Reputation: 120

Symfony Event Listener: kernel.controller

I have a controller like this:

class ArticleController extends Controller implements AuthControllerInterface
{
    public function listAllArticleAction (Request $request)
    {
        // ... ignore
    }
    public function addArticleAction (Request $request)
    {
        // ... ignore
    }
    // ... another article control method
}

Users who want to add article must log in, however, user can visit listAllArticleAction without logging in.

I try to use Event Listener to solve the problem:

class AuthListener
{
    private $m_router;

    public function __construct(Router $router)
    {
        $this->m_router = $router;
    }

    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();

        if ($controller[0] instanceof AuthControllerInterface) {
            $session = $event->getRequest()->getSession()->get('userId');
            if (!isset($session)) {
                $redirectUrl = $this->m_router->generate('page.login');
                $event->setController(function () use ($redirectUrl){
                   return new RedirectResponse($redirectUrl);
                });
            }
        }
    }
}

If user doesn't login, user will be redirected to login page, however, this approach also takes effect on "listAllArticleAction" method.

I think that checking session at the start of the function is not a good idea, because I have another article control methods such as "deleteArticle", "getArticle" and so on, some of them need to log in first, and the others not.

How do I implement this function with event listener? Or, is there any better way to do this?

Upvotes: 0

Views: 1693

Answers (2)

stephan.mada
stephan.mada

Reputation: 1130

The right way to do that is :

class ArticleController extends Controller
{
    public function listAllArticleAction (Request $request)
    {
        // ... ignore
    }
    public function addArticleAction (Request $request)
    {
        if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
            throw $this->createAccessDeniedException();
        }
        // ... ignore
    }
    // ... another article control method
}

If your user is not logged in, they will be redirected to the login page

Upvotes: 0

Jakub Matczak
Jakub Matczak

Reputation: 15656

You're trying to do manually something that is already implemented in Symfony.

You have a two ways to do that. Take a look on documentation of Security Component

Use access_control section in security configuration (security.yml or via annotations)

See also How Does the Security access_control Work?

In YAML configuration it would be something like:

security:
    access_control:        
        - { path: ^/path/to/add_article, roles: IS_AUTHENTICATED_REMEMBERED }

Check if used is logged at the begining of action

if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
    throw $this->createAccessDeniedException();
}

Upvotes: 2

Related Questions