Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SF][Symfony3.1]Dwa panele użytkownika i administracyjny
Forum PHP.pl > Forum > PHP > Frameworki
mariio81
Witam, piszę aplikację w której będą dwa oddzielne systemy logowania, panel dla użytkowników i panel administracyjny. Do panelu administracyjnego zalogować się będą mogli tylko administratorzy. Wykorzystuję do tego FOSUserBundle. Logowanie do panelu użytkownika zrobiłem na domyślnych kontrolerach i widokach. Z jednym panelem wszystko działa bez problemu ale przy dwóch jest problem z wysłaniem danych logowania. Zrobiłem w bazie dwie jednakowe tabele fos_user i fos_admin. Według dokumentacji do config.yml dodałem:
  1. fos_user:
  2. db_driver: orm
  3. firewall_name: panel
  4. user_class: AppBundle\Entity\User
  5. service:
  6. mailer: fos_user.mailer.twig_swift
  7. resetting:
  8. email:
  9. template: email/password_resetting.email.twig
  10. registration:
  11. confirmation:
  12. enabled: true
  13. template: FOSUserBundle:Registration:email.txt.twig
  14. firewall_name: admin
  15. user_class: AppBundle\Entity\Admin


A w security.yml:
  1. providers:
  2. admin:
  3. entity:
  4. class: AppBundle:Admin
  5. property: username
  6. user:
  7. entity:
  8. class: AppBundle:User
  9. property: username
  10.  
  11. firewalls:
  12. dev:
  13. pattern: ^/(_(profiler|wdt)|css|images|js)/
  14. security: false
  15.  
  16. panel:
  17. pattern: ^/panel
  18. form_login:
  19. provider: user
  20. login_path: /panel/logowanie
  21. check_path: /panel/login_check
  22. failure_path: /panel/logowanie
  23. csrf_token_generator: security.csrf.token_manager
  24. always_use_default_target_path: true
  25. default_target_path: /panel/pulpit
  26. logout:
  27. path: /panel/wyloguj
  28. target: /panel/logowanie
  29. anonymous: true
  30.  
  31. admin:
  32. pattern: ^/admin
  33. form_login:
  34. provider: admin
  35. login_path: /admin/logowanie
  36. check_path: /admin/login_check
  37. failure_path: /admin/logowanie
  38. csrf_token_generator: security.csrf.token_manager
  39. always_use_default_target_path: true
  40. default_target_path: /admin/pulpit
  41. logout:
  42. path: /admin/wyloguj
  43. target: /admin/logowanie
  44. anonymous: true
  45.  
  46. access_control:
  47. - { path: ^/panel/logowanie$, role: IS_AUTHENTICATED_ANONYMOUSLY }
  48. - { path: ^/panel/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
  49. - { path: ^/panel/rejestracja, role: IS_AUTHENTICATED_ANONYMOUSLY }
  50. - { path: ^/panel/*, role: ROLE_USER }
  51.   - { path: ^/admin/logowanie$, role: IS_AUTHENTICATED_ANONYMOUSLY }
  52.   - { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
  53.   - { path: ^/admin/*, role: ROLE_ADMIN }



A w routing.yml wpisy odpowiedzialne za logowanie:
  1. fos_user:
  2. resource: "@FOSUserBundle/Resources/config/routing/all.xml"
  3.  
  4. fos_user_security_login:
  5. path: /panel/logowanie
  6. defaults: { _controller: FOSUserBundle:Security:login, _method: POST }
  7.  
  8. fos_user_security_check:
  9. path: /panel/login_check
  10. defaults: { _controller: FOSUserBundle:Security:check }
  11.  
  12. fos_admin_security_login:
  13. path: /admin/logowanie
  14. defaults: { _controller: AppBundle:Security:login, _method: POST }
  15.  
  16. fos_admin_security_check:
  17. path: /admin/login_check
  18. defaults: { _controller: AppBundle:Security:check }


Do logowania do panelu administracyjnego nadpisałem domyślne kontrolery i widoki i tu jest problem bo po wysłaniu formularza logowania przekierowuje mnie na stronę logowania do panelu użytkownika i dostaję że dane są nie poprawne. Wygląda to tak jakby sprawdzało dane logowania do panelu admina w tabeli fos_user a powinno w tabeli fos_admin.
Nie wiem czy dobrze to wszystko robię ale takie coś poskładałem z tego co znalazłem w sieci i widzę że nie działa to.
Pilsener
1. Chcesz zrobić coś niestandardowego? To nie używasz dodatków typu FOSUserBundle
2. Po co dwa oddzielne systemy? Nie wiem nawet, czy tak się da, na pewno trzeba wtedy napisać własny user provider, login/logout handler i oczywiście kontrolery/akcje. Czemu nie może być jeden system a tylko różne formularze logowania jeśli jest taka potrzeba?
mariio81
Poprawiłem kod z pierwszego posta teraz jest czytelny. Może źle to trochę napisałem nie chodzi o dwa systemy bo system będzie jeden tylko dwa oddzielne panele logowania. To z wykorzystaniem FOSUserBundle da rady się zrobić takie coś działające czy jednak jest to niestandardowe rozwiązanie które muszę sam napisać?
Damonsson
FOSUserBundle nie pozwala na coś takiego. Duplikujesz firewall_name w config.yml dla fos_user. Nie możesz tego robić, może być tylko jedna wartość, więc brana jest 1. firewall_name: panel.

Rozwiązanie? Najłatwiej byłoby Ci nadpisać fos_user.listener.authentication i tam zrobić robotę. Albo jeszcze prościej, dołóż sobie Bundla, który robi to co chcesz: https://github.com/PUGX/PUGXMultiUserBundle
mariio81
Teraz mi to działa, problemem było to że źle nadpisywałem widoki. Ogólnie logowanie do panelu obsługuje fosuser a do panelu admina mam w AppBundle SecurityController który obsługuje logowanie do panelu admina a w App/Resources/views widoki. Ogólnie działa bo po zalogowaniu do panelu użytkownika gdy wchodzę na strony panelu admina pojawia się strona logowania i tak samo po zalogowaniu do panelu admin więc działa to tak jak chciałem. Tylko w takim przypadku nie będzie działo przypomnienie hasła i edycja profilu admina. Będę raczej musiał skorzystać z bundla PUGXMultiUserBundle.
Boshi
Może czegoś nie rozumiem, ale po co ci dwa panele logowania? skoro masz administratorów i użytkowników to robisz jeden normalny panel (z fosuser) i rolami sprawdzasz kto jest kim.. jak Administrator to wywalasz go do panelu jak użytkownik to do strony głównej.. albo wszystkich do strony głównej tylko w zależności od uprawnień pokazujesz odpowiednie linki czy co tam chcesz.
mariio81
W założeniu miało być tak że admini mają swój oddzielny panel a użytkownicy oddzielny zintegrowany ze stroną ale w sumie na podstawie ról też by można było wyświetlać odpowiednie widoki. Słuszna uwaga. Dzięki za odpowiedź.

Witam, zrobiłem logowanie według porad jedna tabela, różne role. W sieci znalazłem przykład jak wykorzystać loginSuccessHandler żeby przekierowało użytkownika w zależności od roli albo do panelu usera albo do panelu admin, i to działa. Do tego jeszcze chciałem dorobić coś gdyby użytkownik zalogował się do swojego panelu i próbował wejść na strony panelu admina, to żeby go gdzieś przekierowało albo wyświetliło że niema takiej strony. Znalazłem coś że można nadpisać widoki ze stronami błędów albo napisać exceptionListener lub z wykorzystaniem access_denied_url. Który ze sposobów powinienem wykorzystać?
Pilsener
Dość standardowe podejście to użycie adnotacji:
Kod
* @Security("has_role('ROLE_ADMIN')")


I masz potem wyjątek AccessDeniedException, z którym możesz:
- nic nie robić (użytkownik zobaczy np. error 401)
- coś zrobić, np. wstawić jedną, uniwersalną stronę błędu typu "no content" dla wszystkich wyjątków (żeby nikt nie wiedział, czy to brak dostępu czy strona nie istnieje) lub też obsłużyć to inaczej wg potrzeb klienta (czasem klient chce wiedzieć, czy brak dostępu czy brak zasobu, wtedy już muszą być obsługiwane minimum dwa przypadki)

Przekierowania nie są dobre (z bardzo wielu powodów) i należy ich unikać.
mariio81
A gdzie mogę znaleźć jakąś instrukcję jak taki wyjątek obsłużyć?
Pilsener
Zapewne w dokumentacji:
https://symfony.com/doc/current/controller/error_pages.html

Od prostej podmianki templatek, po zaawansowane serwisy typu ExceptionHandler.
mariio81
Widziałem to i tu nie ma problemu. Bardziej bym powiedział, że chodzi o ExceptionHandler. W dokumentacji znalazłem takie coś:
https://symfony.com/doc/current/security/ac...ed_handler.html
Myślę, że to powinno wystarczyć.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.