根据身份验证路由到不同的控制器

时间:2017-04-01 13:26:37

标签: php symfony security routing

在使用Symfony2重写应用程序时,我试图保留一些遗留行为,并且正在寻找一个干净的解决方案。

我的目标是拥有URI" /"如果用户未登录,则显示启动页面,如果登录,则相同的URI显示每用户仪表板。

解决方案还需要具有可扩展性 - " public"在私人网站上有不同表现形式的网站。网站(即索引,支持,关于,联系等) - 因此,我不能简单地使用全能路线并转发给正确的控制器。

我有一个可能的解决方案,我将作为答案发布,但我正在寻找有关更好方法的建议。

2 个答案:

答案 0 :(得分:0)

N.B。这个答案是一个黑客攻击;我发布它是希望找到更好的方法。

实现这一目标的一种方法是利用路由系统对conditions的支持 - 这样做的好处是不会影响URL生成并允许路由系统处理参数等。

但是,为了将条件用于此目的,我们需要通过Request或RequestContext(仅有两个可用变量)公开请求的身份验证状态。

这可以通过创建一个在RouterListener之前运行的EventListener来完成,并将身份验证状态存储在Request的属性中。

不幸的是,如event reference所示,防火墙仅在RouterListener之后运行,这意味着我们的侦听器中无法使用身份验证状态。

据我所知,唯一的解决方案是修改优先级,使防火墙首先运行,然后是新的EventListener,最后是RouterListener。这几乎绝对是一个坏主意,可能会导致意想不到的效果。

我欢迎任何有关如何实现这一目标的更好建议。

答案 1 :(得分:0)

我在使用symfony3,但这是我的方法。登录后,我将所有用户发送到/ login / redirect,控制器如下所示。它很简单,并使用内置的ROLES_ *功能。

/**
 * Redirect users after login based on various checks
 *
 * @Route("/login/redirect", name="_login_redirect")
 */
public function loginRedirectAction()
{
    // Send user to admin page or order page based on credentials
    if ($this->isGranted('ROLE_SUPERUSER')) {
        return $this->redirectToRoute('admin_home');
    } elseif ($this->isGranted('ROLE_ADMIN')) {
        return $this->redirectToRoute('dashboard');
    } else {
        return $this->redirectToRoute('order_page');
    }
}

为了处理那些未登录的人,我在twig模板中使用了一些简单的逻辑。请注意,symfony会自动为所有登录用户提供ROLES_USER角色。

    {% if is_granted('ROLE_USER') %}
        {# User is logged in, do something appropriate #}
        <li>{{ app.user ? app.user.name : '' }}</li>&nbsp;
        {# Useful stuff #}
    {% else %}
        {# Show login link, or give other info #}
        <li><a href="{{ path('security_login') }}">Login</a></li>
    {% endif %}