简体   繁体   English

Symfony事件监听器:kernel.controller

[英]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. 想要添加文章的用户必须登录,但是,用户无需登录即可访问listAllArticleAction。

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. 如果用户未登录,则将用户重定向到登录页面,但是,此方法也对“ listAllArticleAction”方法生效。

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. 我认为在函数开始时检查会话不是一个好主意,因为我还有另一种文章控制方法,例如“ deleteArticle”,“ getArticle”等,其中一些需要首先登录,而其他则不需要。

How do I implement this function with event listener? 如何使用事件监听器实现此功能? Or, is there any better way to do this? 或者,有没有更好的方法可以做到这一点?

You're trying to do manually something that is already implemented in Symfony. 您正在尝试手动执行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) 使用安全性配置中的access_control部分(security.yml或通过注释)

See also How Does the Security access_control Work? 另请参阅安全性access_control如何工作?

In YAML configuration it would be something like: 在YAML配置中,它将类似于:

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();
}

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 如果您的用户未登录,他们将被重定向到登录页面

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM