W mojej aplikacji Symfony 2 mam 3 różne role użytkowników, które mogą mieć dostęp do części administracyjnej backend:związania jednej trasy do różnych sterowników w zależności od ról użytkowników
role_hierarchy:
ROLE_STAFF: ROLE_USER
ROLE_MODERATOR: ROLE_STAFF
ROLE_ADMIN: ROLE_MODERATOR
Na trasie jak http://example.org/admin/post/
, ja podobnie jak moja aplikacja do wyświetlania różnych informacji w zależności od roli użytkownika, czyli 3 kontrolerów powiązanie z tylko trasą.
Jaki jest najlepszy sposób, aby sobie z tym poradzić?
Myślałam o pewnych rozwiązań, ale nikt zdaje się być dobre dla mnie:
Jeden sterownik, iw każdym działaniu Właśnie testy rola użytkownika:
<?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); } }
Nawet jeśli to robi praca, IMO oczywiście to nie jest dobry projekt.
Jeden BackendController że wysyła do 3 różnych regulatorów:
<?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; } }
samo jak numer jeden.
Starałem się uczynić kontrolery rozciąga się nawzajem:
<?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 jest to lepszy projekt, ale nie uda się zrobić to działa. System routingu zatrzymuje się na pierwszym kontrolowanym kontrolerze. Chciałbym, aby działał automatycznie w stylu kaskadowym automatycznie (tj. Jeśli użytkownik jest personelem, wówczas należy przejść do PostStaffController, w przeciwnym razie, jeśli użytkownik jest moderatorem, przejdź do PostModeratorController, w przeciwnym razie przejdź do PostAdminController).
Dodaj detektora do kernel.controller w moim BlogBundle, który wykona tę samą pracę co numer 2?
Szukam najlepiej zaprojektowanego i bardziej elastycznego rozwiązania, ponieważ istnieje szansa, że dodamy więcej ról w przyszłości.
Mam do czynienia z dokładnie taką samą sytuacją, czy znalazłeś dobre rozwiązanie? –
Wszystkie rozwiązania są dobre, ale są źle zaprojektowane. Jeśli napotkasz ten sam problem, najpierw upewnij się, że to nie jest zła koncepcja twojej aplikacji. W moim przypadku zamiast tego zrobiłem 2 różne formy dla mojej jednostki: "konfiguracja" i "personalizacja". Dzięki temu administrator ma dostęp do kontrolerów "konfiguracyjnych" i "dostosowawczych", a personel i moderator może uzyskać dostęp tylko do "dostosowywania". Nie jestem pewien, czy jest jasne. Być może powinienem zrobić to kompletną odpowiedź? – iamdto
Masz rację, to był zły projekt. Moim rozwiązaniem było rozdzielenie różnych obszarów aplikacji w różnych pakietach, w których mogę odpowiednio zarządzać rolami. Dzięki. –