基于用户角色的菜单项过滤

4
我在我的网站上有多个用户角色。一些控制器基于用户角色有访问限制。
我还有一个菜单(基于 KnpMenuBundle),我需要只包含对已登录用户可访问的条目。
目前,我决定按以下方式过滤项目:
1. 对所有受保护路由添加一个新选项roles:例如 roles: [ROLE_ADMIN, ROLE_MANAGER]
2. 在菜单构建期间将当前用户角色与该选项匹配。
我试图找出Symfony中是否存在这样的功能(我的意思是在路由设置中定义角色限制),但我没有找到类似的东西。
所以我的问题是:
1. 如何基于用户角色过滤菜单项?(也许已经有了这样的功能?)
如果上一个问题的答案是“否”,那么:
2. 我如何构建这样的过滤机制? 正如我已经提到的,在这种情况下,我决定添加一个新选项,那么最好的做法是什么?
1个回答

3
也许你可以以我的KnpMenu Builder为例?
namespace AppBundle\Menu;

use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAware;

class Builder extends ContainerAware
{
    public function mainMenu(FactoryInterface $factory, array $options)
    {
        $sc = $this->container->get('security.context');

        $menu = $factory->createItem('root');
        $menu->setChildrenAttribute('class', 'nav navbar-nav');

        $menu->addChild('About us', array('route' => 'about'));
        $menu->addChild('Contact', array('route' => 'contact'));

        /*
         * before we use isGranted() we have to check if the security is available, otherwise we will receive an exception on the custom error pages. See also
         * http://symfony.com/doc/current/cookbook/controller/error_pages.html#avoiding-exceptions-when-using-security-functions-in-error-templates
         */
        if($sc->getToken())
        {
            $menu->addChild('Members', array('uri' => '#'))
                            ->setAttribute('dropdown', true);

            if($sc->isGranted('IS_AUTHENTICATED_REMEMBERED'))
            {
                $menu['Members']->addChild('My profile', array('route' => 'fos_user_profile_show'));

                if($sc->isGranted('ROLE_ADMIN'))
                {
                    $menu['Members']->addChild('Dashboard', array('route' => 'sonata_admin_dashboard'))
                                    ->setAttribute('divider_append', true);
                }

                $menu['Members']->addChild('Logout', array('route' => 'fos_user_security_logout'));
            }
            else
            {
                $menu['Members']->addChild('Login', array('route' => 'fos_user_security_login'));
                $menu['Members']->addChild('Registration', array('route' => 'fos_user_registration_register')); 
            }
        }

        return $menu;
    }

}

好的,谢谢分享,你的方法很有效 =)。如果我找不到更适合我的需求,我会使用它。 我认为最好将这些角色限制放在一个地方(例如路由设置),因为应该在相应的控制器中添加相同的检查(通过isGranteddenyAccessUnlessGranted)。 如果我成功在路由器设置中添加角色限制,那么我可以统一执行此类检查。 - Vasily

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接