根据身份验证将一个 url 路由到两个控制器操作

Routing one url to two controller actions based on authentication

我对 Symfony 有点陌生,但我有一个很容易解释的情况:

我有一个 public 主页和一个私人主页。我想通过 URL "/"

访问这两个

当未经身份验证的人访问地址 www.example.com/ 我希望将他们路由到 PublicController::indexAction()

当经过身份验证的用户访问地址 www.example.com/ 我希望将他们路由到 Privatecontroller::indexAction()

这可能吗?

(symfony 2.7 顺便说一下)

绝对有可能,尽管细节取决于您在每个控制器操作中所做的事情。最简单的方法是:

class PublicController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
    public function indexAction()
    {
        if ($this->getUser() !== null) {
            return $this->forward('BundleName:PrivateController:index');
        }

        // do public controller details
    }
}

所以默认情况下每个人都会被发送到 PublicController:indexAction,它会检查是否有登录用户(使用来自 Symfony 的控制器 class 的 getUser 方法)以及是否forward the requestPrivateController:indexAction。如果不是,那么它只是按预期显示 public 操作。如果您期望登录用户多于注销用户,则可以反转此设置,因为转发会降低性能(因为 Symfony 将创建并发送子请求)。

更长的答案是了解您在每个需要它们分开的控制器中所做的事情,以及您是否可以将功能组合到服务中或以其他方式重新构建它们。在不了解您的特定问题领域的更多信息的情况下,以上似乎是最好的前进方式。

在 Symfony 上获得了 social network 启动 运行(总是使用最新版本)所以我很自然地遇到了在主页上显示不同内容的挑战首先取决于您的登录状态,以及其次,如果根据您登录的用户 ID 登录不同的个性化内容。虽然上面的答案有效,但我发现使用 twig 显示哪些内容更好,性能更好,因为我可以使用 render_esi 标记来使用反向代理缓存,不仅避免了数据库查找,还避免了模板生成和整个请求击中 Symfony。

例如

{# src/MyApp/AppBundle/Resources/views/Page/index.html.twig #}
{% extends 'MyAppAppBundle::layout.html.twig' %}
.....
    {% block body %}
        {% if not app.user %}
Code for non-logged in user
e.g. {{ render_esi(controller('MyAppAppBundle:Home:non_logged_in_user')) }}
        {% else %}
Code for logged in user
e.g {{ render_esi(controller('controller('MyAppAppBundle:Home:logged_in_user', { 'user': app.user.id })) }}
        {% endif %}
....
    {% endblock %}