Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [inne] Logowanie przy użyciu userInterface w Symfony
Forum PHP.pl > Forum > Przedszkole
kosmos
Mam klasę Uzytkownik która jest odwzorowaniem tabeli Uzytkownik w BD.
Korzystając z dokumentacji Symfony, a konkretnie rozdziału "System bezpieczeństwa" chcę skorzystać z wbudowanego modułu logowania (tak to rozumiem).
a więc:
1. Dodałem dziedziczenie po UserInterface
  1. <?php
  2.  
  3. namespace Nomad\SystemBundle\Entity;
  4. use Symfony\Component\Security\Core\User\UserInterface;
  5.  
  6. use Doctrine\ORM\Mapping as ORM;
  7.  
  8. class Uzytkownik implements UserInterface
  9. {
  10. protected $id_uzytkownik;
  11. protected $login;
  12. protected $haslo;
  13. protected $email;
  14. protected $upr;
  15.  
  16. /**
  17.   * Get id_uzytkownik
  18.   *
  19.   * @return integer
  20.   */
  21. public function getIdUzytkownik()
  22. {
  23. return $this->id_uzytkownik;
  24. }
  25.  
  26. /**
  27.   * Set login
  28.   *
  29.   * @param string $login
  30.   * @return Uzytkownik
  31.   */
  32. public function setLogin($login)
  33. {
  34. $this->login = $login;
  35.  
  36. return $this;
  37. }
  38.  
  39. /**
  40.   * Get login
  41.   *
  42.   * @return string
  43.   */
  44. public function getLogin()
  45. {
  46. return $this->login;
  47. }
  48.  
  49. /**
  50.   * Set haslo
  51.   *
  52.   * @param string $haslo
  53.   * @return Uzytkownik
  54.   */
  55. public function setHaslo($haslo)
  56. {
  57. $this->haslo = $haslo;
  58.  
  59. return $this;
  60. }
  61.  
  62. /**
  63.   * Get haslo
  64.   *
  65.   * @return string
  66.   */
  67. public function getHaslo()
  68. {
  69. return $this->haslo;
  70. }
  71.  
  72. /**
  73.   * Set email
  74.   *
  75.   * @param string $email
  76.   * @return Uzytkownik
  77.   */
  78. public function setEmail($email)
  79. {
  80. $this->email = $email;
  81.  
  82. return $this;
  83. }
  84.  
  85. /**
  86.   * Get email
  87.   *
  88.   * @return string
  89.   */
  90. public function getEmail()
  91. {
  92. return $this->email;
  93. }
  94.  
  95. /**
  96.   * Set upr
  97.   *
  98.   * @param string $upr
  99.   * @return Uzytkownik
  100.   */
  101. public function setUpr($upr)
  102. {
  103. $this->upr = $upr;
  104.  
  105. return $this;
  106. }
  107.  
  108. /**
  109.   * Get upr
  110.   *
  111.   * @return string
  112.   */
  113. public function getUpr()
  114. {
  115. return $this->upr;
  116. }
  117. }
  118.  
  119. }


2. Skonfigurowałem security.yml
  1. security:
  2. encoders:
  3. Symfony\Component\Security\Core\User\User: plaintext
  4. Nomad\SystemBundle\Entity\Uzytkownik: sha512
  5.  
  6. role_hierarchy:
  7. ROLE_ADMIN: ROLE_USER
  8. ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
  9.  
  10. providers:
  11. in_memory:
  12. memory:
  13. users:
  14. user: { password: userpass, roles: [ 'ROLE_USER' ] }
  15. admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
  16. main:
  17. entity: { class: Nomad\SystemBundle\Entity\Uzytkownik, property: login }
  18.  
  19.  
  20.  
  21.  
  22. firewalls:
  23. dev:
  24. pattern: ^/(_(profiler|wdt)|css|images|js)/
  25. security: false
  26.  
  27. demo_login:
  28. pattern: ^/demo/secured/login$
  29. security: false
  30.  
  31. demo_secured_area:
  32. pattern: ^/demo/secured/
  33. form_login:
  34. check_path: _demo_security_check
  35. login_path: _demo_login
  36. logout:
  37. path: _demo_logout
  38. target: _demo
  39. #anonymous: ~
  40. #http_basic:
  41. # realm: "Secured Demo Area"
  42.  
  43. access_control:
  44. #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }


i pojawia się error:
Error: Class Nomad\SystemBundle\Entity\Uzytkownik contains 5 abstract methods and must therefore be declared abstract or implement the remaining methods (Symfony\Component\Security\Core\User\UserInterface::getRoles, Symfony\Component\Security\Core\User\UserInterface::getPassword, Symfony\Component\Security\Core\User\UserInterface::getSalt, ...) in C:\xampp\htdocs\Projekt\src\Nomad\SystemBundle\Entity\Uzytkownik.php line 117

Postąpiłem zgodnie z dumentacją a nagle pojawia się masa problemów ...
memory
UserInterface jest to interfejs, który wymusza na tobie aby klasa Uzytkownik posiadała wymagane metody zawarte w UserInterface
kosmos
i pewnie jeszcze klasa musi nazywać się user a nie uzytkownik?

pitu
Poczytaj o interfejsach...
kosmos
Ok. pocztałem i przypomniałem sobie.
Błąd zniknął, formularz logowania wyświetla się.
Mam natomiast problem z dalszą jego obsługą.
W Internecie nie mogę znaleźć żadnego przykładu, nakierowania.
Znajdzie się ktoś miły aby pomóc?

W kontrolerze wywołuję taką metodę:
  1. public function logformAction(Request $request){
  2. $uzytkownik = new uzytkownik();
  3. $form = $this->createForm(new Logowanie(), $uzytkownik); //Tworzę formularz logowania
  4. $form->handleRequest($request);
  5.  
  6. if ($form->isValid()) { //jeśli formularz jest pprawny i podano login oraz hasło tu powinno nastąpić sprawdzenie danych przesłanych formularzem z danymi w bazie wraz ze zwróceniem wyniu.
  7.  
  8.  
  9.  
  10. if (!$uzytkownik) {
  11. throw $this->createNotFoundException('No uzytkownik found'/*.$id_uzytkownik*/);
  12. }
  13.  
  14. if ($uzytkownik) {
  15. return new Response('Znaleziono użytkownika '.$uzytkownik->getLogin());
  16. }
  17. }
  18.  
  19. return $this->render('NomadSystemBundle:Default:index.html.twig', array('form' => $form->createView(),));
  20. }


Brakuje mi tego kawałka kodu który dałem wyżej w komentarzu i nigdzie nie mogę znaleźć informacji, przykładu.
Pomożecie?
pedro84
Bardzo słabo szukasz. W dokumentacji komponentu Security masz przykład akcji kontrolera: Using a Traditional Login Form
kosmos
Kontynując temat, jako że jestem totalnie zielony w tym temacie, wróciłem do początu pozostawiając póki co logowanie przy pomocy bazy danych. Najpierw chcę nauczyć się logowania za pomocą użytkowników zadeklarowanych w pliku security.yml.

Zrobiłem tak jak jest napisane w dokumentacji (przynajmniej tak mi się wydaje) i trzymałem takie pliki z następującym błędem w security.yml

app/config/routing.yml bez zmian
  1. acme_logowanie:
  2. resource: "@AcmeLogowanieBundle/Resources/config/routing.yml"
  3. prefix: /


src/Acme/LogowanieBundle/Resources/config/routing.yml
  1. acme_logowanie_homepage:
  2. path: /hello/{name}
  3. defaults: { _controller: AcmeLogowanieBundle:Default:index }
  4.  
  5. login:
  6. pattern: /login
  7. defaults: { _controller: AcmeLogowanieBundle:Default:login }
  8. login_check:
  9. pattern: /login_check


app/config/security.yml
  1. security:
  2. encoders:
  3. Symfony\Component\Security\Core\User\User: plaintext
  4.  
  5. role_hierarchy:
  6. ROLE_ADMIN: ROLE_USER
  7. ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
  8.  
  9. providers:
  10. in_memory:
  11. memory:
  12. users:
  13. ryan: { password: ryanpass, roles: [ 'ROLE_USER' ] }
  14. admin: { password: kitten, roles: [ 'ROLE_ADMIN' ] }
  15.  
  16. firewalls:
  17. login_firewall:
  18. pattern: ^/login$
  19. anonymous: ~
  20. secured_area:
  21. pattern: ^/
  22. form_login: ~
  23. login_path: login
  24. check_path: login_check


src/Acme/LogowanieBundle/Controller/DefaultController.php

  1. <?php
  2. // src/Acme/LogowanieBundle/Controller/DefaultController.php;
  3. namespace Acme\LogowanieBundle\Controller;
  4.  
  5. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  6. use Symfony\Component\Security\Core\SecurityContext;
  7.  
  8. class DefaultController extends Controller
  9. {
  10. public function loginAction()
  11. {
  12. $request = $this->getRequest();
  13. $session = $request->getSession();
  14.  
  15. // get the login error if there is one
  16. if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
  17. $error = $request->attributes->get(
  18. SecurityContext::AUTHENTICATION_ERROR
  19. );
  20. } else {
  21. $error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
  22. $session->remove(SecurityContext::AUTHENTICATION_ERROR);
  23. }
  24.  
  25. return $this->render(
  26. 'AcmeLogowanieBundle:Security:login.html.twig',
  27. // last username entered by the user
  28. 'last_username' => $session->get(SecurityContext::LAST_USERNAME),
  29. 'error' => $error,
  30. )
  31. );
  32. }
  33. }


src/Acme/LogowanieBundle/Resources/views/Security/login.html.twig
  1. {# src/Acme/LogowanieBundle/Resources/views/Security/login.html.twig #}
  2. {% if error %}
  3. <div>{{ error.message }}</div>
  4. {% endif %}
  5.  
  6. <form action="{{ path('login_check') }}" method="post">
  7. <label for="username">Username:</label>
  8. <input type="text" id="username" name="_username" value="{{ last_username }}" />
  9.  
  10. <label for="password">Password:</label>
  11. <input type="password" id="password" name="_password" />
  12.  
  13. {#
  14. If you want to control the URL the user is redirected to on success (more details below)
  15. <input type="hidden" name="_target_path" value="/account" />
  16. #}
  17.  
  18. <button type="submit">login</button>
  19. </form>


BŁĄD:

FileLoaderLoadException: Cannot import resource "C:\xampp\htdocs\Logowanie3\app/config\security.yml" from "C:\xampp\htdocs\Logowanie3\app/config\config.yml". (Unable to parse at line 23 (near " login_path: login").)

Co jest źle w tym pliku?
kpt_lucek
  1. form_login: ~
  2. login_path: login
  3. check_path: login_check


Powodzenia
kosmos
Mogę prosić o jakąś konstruktywną wypowiedź a nie tylko powodzenia?
Czy chodzi o to że jeśli będę miał
  1. form_login: ~

dalsze
  1. login_path: login
  2. check_path: login_check

są jakby niewidoczne?

Dobrze ... chyba sam odpowiedziałem sobie na to pytanie.

Teraz po wpisaniu adresu:
  1. http://localhost/Logowanie3/web/app_dev.php/login

Wyświetla mi się formularz logowania.
Jeśli podam błędne dane, aplikacja wraca do formularza logowania z informacją:
  1. Bad credentials

Niestety po podaniu poprawnych danych, mam taki oto komunikat;
  1. No route found for "GET /" (from "http://localhost/Logowanie3/web/app_dev.php/login")

Czyli jak rozumim nie mam określonej trasy w przypadku poprawnego logowania. Czy chodzi tu o ten fragment w routing.yml?
  1. login_check:
  2. pattern: /login_check
kpt_lucek
Jeżeli dobrze pamiętam składnię YML, to zapis:
  1. form_login:
  2. login_path: login
  3. check_path: login_check

utworzy tablicę ['form_login'] zawierającą elementy ['login_path'] => login, ['check_path'] => login_check

W przypadku
  1. form_login: ~
  2. login_path: login
  3. check_path: login_check

Nawiązując do ostatniego podanego przeze mnie linku w tym poście: The tilde (~) is yaml syntax for "null" and just means there are no options.
Poza tym polecam Ci State of YAML php

Dodatkowo, autor TEGO tematu zadał kilka ciekawych pytań, którymi mógłbyś się zainteresować.

--EDIT

  1. No route found for "GET /" (from "http://localhost/Logowanie3/web/app_dev.php/login")


Oznacza że żaden z includowanych plików określających routing nie zawiera akcji kontrolera dla adresu "/"
kosmos
kpt_lucek
dzięki za wytłumaczenie problemu w security.yml i artyuły - zapoznam się.
Nie rozumiem niestety ostatniego komunikatu błędu. Dlaczego komunikat odwołuje się do pliku app_dev.php? jak należy obsłużyć ten błąd?
Nie wiem również jak ma zachować się aplikacja po poprawnym zalogowaniu z przytoczonego przykładu dokumentacji.
kpt_lucek
Po zalogowaniu jesteś przekierowany na adres "/", dla którego nie masz akcji w kontrolerze. Dodaj takową i będzie po problemie (routing bundla i kontroler bundla).
kosmos
O ile dobrze Cię zrozumiałem dodałem:

  1. acme_logowanie_homepage:
  2. path: /hello/{name}
  3. defaults: { _controller: AcmeLogowanieBundle:Default:index }
  4.  
  5. login:
  6. pattern: /login
  7. defaults: { _controller: AcmeLogowanieBundle:Default:login }
  8. login_check:
  9. pattern: /login_check
  10. defaults: { _controller: AcmeLogowanieBundle:Default:logintrue }


a w kontrolerze:
  1. public function logintrueAction(){
  2.  
  3. return $this->render('AcmeLogowanieBundle:Default:index.html.twig');
  4. }


Jednak błąd nadal się pojawia.

Dlaczego po poprawnym zalogowaniu apliacja chce przejść do adresu /, wydawało mi się że przejdzie do /login_check i wywoła metodę logintrue kontrolera.
pedro84
Akcją formularza logowania powinna być trasa login_check. Po poprawnym zalogowaniu, przekieruje Cię do / (dalej nie masz). Domyślą trasę przekierowania możesz zmienić:
Kod
default_target_path:            /
.
Tutaj masz wszystkie opcje konfiguracyjne komponentu Security. Poczytaj najpierw jak wszystko działa, jak się konfiguruje, bo masz spore braki w podstawach.
kosmos
Dzęki pedro84

  1. form_login:
  2. login_path: login
  3. check_path: login_check
  4. default_target_path: /login_check


rozwiązało sprawę. O to mi właśnie chodziło. Nie wiedziałem dlaczego aplikacja chciała od razu przekierowywać mnie do "/" bo przecież nigdzie takiej ścieżki nie określiłem. Teraz już wiem skąd to się bierze, dzięki Waszej pomocy.
Przykład logowania przy użyciu formularza z użytkownikami zadeklarowanymi w pliku działa smile.gif !
pedro84
Cytat(kosmos @ 26.07.2014, 15:17:07 ) *
Nie wiedziałem dlaczego aplikacja chciała od razu przekierowywać mnie do "/" bo przecież nigdzie takiej ścieżki nie określiłem.

Dlatego zasugerowałem Ci dokładne przeczytanie dokumentacji, bo tam jest to napisane wink.gif Generalnie w dokumentacji SF czy to komponentów, można znaleźć dosłownie wszystko co potrzebne.
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.