gpt4 book ai didi

symfony - 根据用户角色将一个路由绑定(bind)到不同的 Controller

转载 作者:行者123 更新时间:2023-12-04 08:53:02 25 4
gpt4 key购买 nike

在我的 Symfony 2 应用程序中,我有 3 个不同的用户角色可以访问后端管理部分:

role_hierarchy:
ROLE_STAFF: ROLE_USER
ROLE_MODERATOR: ROLE_STAFF
ROLE_ADMIN: ROLE_MODERATOR

对于像 http://example.org/admin/post/ 这样的路线, 我希望我的应用根据用户角色显示不同的信息,这意味着 3个 Controller 绑定(bind)到 唯一路线 .

处理此问题的最佳方法是什么?

我正在考虑一些解决方案,但似乎没有一个对我有好处:
  • 一个 Controller ,在每个操作中我只测试用户角色:
    <?php

    /**
    * @Route("/admin/post")
    */
    class PostController extends Controller
    {
    /**
    * Lists all post entities.
    *
    * @Route("/", name="post_index")
    * @Template()
    * @Secure(roles="ROLE_STAFF")
    */
    public function indexAction()
    {
    $user = $this->get('security.context')->getToken()->getUser();

    if ($this->get('security.context')->isGranted('ROLE_STAFF')) {
    // Do ROLE_STAFF related stuff
    } else if ($this->get('security.context')->isGranted('ROLE_MODERATOR')) {
    // Do ROLE_MODERATOR related stuff
    } else if ($this->get('security.context')->isGranted('ROLE_ADMIN')) {
    // Do ROLE_ADMIN related stuff
    }

    return array('posts' => $posts);
    }
    }

    即使这样做了,IMO 显然这不是一个好的设计。
  • 一个 BackendController 分派(dispatch)给 3 个不同的 Controller :
    <?php

    /**
    * @Route("/admin/post")
    */
    class PostBackendController extends Controller
    {
    /**
    * Lists all post entities.
    *
    * @Route("", name="admin_post_index")
    * @Template("AcmeBlogBundle:PostAdmin:index.html.twig")
    * @Secure(roles="ROLE_STAFF")
    */
    public function indexAction()
    {
    if ($this->get('security.context')->isGranted('ROLE_STAFF')) {
    $response = $this->forward('AcmeBlogBundle:PostStaff:index');
    } else if ($this->get('security.context')->isGranted('ROLE_MODERATOR')) {
    $response = $this->forward('AcmeBlogBundle:PostModerator:index');
    } else if ($this->get('security.context')->isGranted('ROLE_ADMIN')) {
    $response = $this->forward('AcmeBlogBundle:PostAdmin:index');
    }

    return $response;
    }
    }

    和一号一样。
  • 我试图让 Controller 相互扩展:
    <?php

    /**
    * @Route("/admin/post")
    */
    class PostStaffController extends Controller
    {
    /**
    * Lists all post entities.
    *
    * @Route("/", name="post_index")
    * @Template()
    * @Secure(roles="ROLE_STAFF")
    */
    public function indexAction()
    {
    $user = $this->get('security.context')->getToken()->getUser();

    // Do ROLE_STAFF related stuff

    return array('posts' => $posts);
    }
    }

    <?php

    /**
    * @Route("/admin/post")
    */
    class PostModeratorController extends PostStaffController
    {
    /**
    * Lists all post entities.
    *
    * @Route("/", name="post_index")
    * @Template()
    * @Secure(roles="ROLE_MODERATOR")
    */
    public function indexAction()
    {
    $user = $this->get('security.context')->getToken()->getUser();

    // As PostModeratorController extends PostStaffController,
    // I can either use parent action or redefine it here

    return array('posts' => $posts);
    }
    }

    <?php

    /**
    * @Route("/admin/post")
    */
    class PostAdminController extends PostModeratorController
    {
    /**
    * Lists all post entities.
    *
    * @Route("/", name="post_index")
    * @Template()
    * @Secure(roles="ROLE_ADMIN")
    */
    public function indexAction()
    {
    $user = $this->get('security.context')->getToken()->getUser();

    // Same applies here

    return array('posts' => $posts);
    }
    }

    IMO 这是一个更好的设计,但我无法让它工作。路由系统在它匹配的第一个 Controller 上停止。我想让它自动成为级联风格的王者(即,如果用户是员工,则转到 PostStaffController,否则如果用户是版主,则转到 PostModeratorController,否则转到 PostAdminController)。
  • 在我的 BlogBu​​ndle 中为 kernel.controller 添加一个监听器,它的工作与数字 2 相同吗?

  • 我正在寻找最好的设计和更灵活的解决方案,我们有机会在 future 增加更多的角色。

    最佳答案

    恕我直言,您不应根据角色为同一路线触发不同的 Controller 。只是职责不同而已。路由用于选择 Controller ,角色用于特权。一年后,您将不记得诀窍,即。当您尝试添加新角色时。

    当然,不同角色不同内容的问题是很常见的,所以在这种情况下我最喜欢的解决方案是:

  • 当不同角色的 Controller 有很大不同时,我会在需要时使用不同的路由和重定向。
  • 当 Controller 相似但内容不同时,即。不同的数据库查询条件,我使用与您类似的解决方案 2. 但不是转发,而是使用来自同一 Controller 的私有(private)/ protected 方法来完成作业。有一个技巧-您必须从上到下检查角色,即。首先检查 ROLE_ADMIN,下一个 ROLE_OPERATOR 和最后一个 ROLE_STAFF,因为当您的 ROLE_ADMIN 从 ROLE_STAFF 继承时,然后阻止用户捕获它。
  • 当差异仅在于应该为不同角色显示/隐藏的某些信息 block 时,我会使用一个 Controller 并检查模板中的角色以确定哪个 block 呈现与否。
  • 关于symfony - 根据用户角色将一个路由绑定(bind)到不同的 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10190305/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com