forked from nfqakademija/kickstart
-
Notifications
You must be signed in to change notification settings - Fork 34
Patogesniam taisymui #304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
aurelijusb
wants to merge
33
commits into
homework-2019-11-19
Choose a base branch
from
indre-sf-hw3
base: homework-2019-11-19
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Patogesniam taisymui #304
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Išnaudokime Symfony teikiamas galimybes naudotojų atpažinomui ir teisių valdymui. Sugeneruota su scipts/backend.sh composer require symfony/security-bundle Per naršyklę nieko nematome, bet galima patikrinti, ar veikia su scripts/backend.sh bin/console config:dump-reference security bin/console debug:config security Sukuriamas pavyzdinis security.yaml failas. dump-reference komanda parodo galimas nustatymų reikšmes. debug:config komanda parodo apskaičiuotas reikšmes (esamus nustatymus). Dokumentacija: https://symfony.com/doc/current/security.html https://symfony.com/doc/current/reference/configuration/debug.html
Profiler toolbar leidžia matyti ne tik kokiu greičiu užsikrovė puslapis, bet ir koks naudotojas yra prisijungęs.
Sugeneruota routes/dev konfigūracija, kad leistų užsikrauti Profiler juostai naudojant AJAX.
Su savimi prideda ir kitas derinimui (angl. debug) skirtas bibliotekas. Pvz {{ dump(kintamas) }} komandą Twig'e.
Sugeneruota su scripts/backend.sh
composer require profiler --dev
Ši biblioteka skirta tik programavimo etapui (angl. development), o ne produkcinei sistemai (žr. require-dev ir ['dev' => true, 'test' => true])
Dokumentacija:
https://symfony.com/doc/current/profiler.html
Galima rašyti viską patiems, arba galima susigeneruoti pavyzdį. MakerBundle standartiškai klausinėja parametrų, bet dėl demonstracijos greičio tiesiog naudojama vienos eilutės komanda (no-interaction). Sugeneruota su scripts/backend.sh ./bin/console make:user User --is-entity --identity-property-name=email --with-password --use-argon2 --no-interaction Naudojami parametrai: --is-entity – duomenys bus saugomi duomenų bazėje --identity-property-name – naudotojai bus atskiriami pagal el. pašto adresą (nes pagal jį dažniausiai galima priminti slaptažodį ir įprasta, kad 1 naudotjas = 1 el. pašto adresas) --with-password – naudojamas slaptažodis --use-argon2 – naudojamas naujausias (PHP 7.3) šifravimo (hash = maišos funkcijos) algoritmas --no-interaction – neklausinėti parametrų (patogiau demostracijai) Dokumentacija: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html
Naudotojo modelį apsirašėme kaip Entity klasę, bet vis tiek reikia, kad duomenų bazėje būtų atitinkamos lentelės. Sugeneruota su scripts/backend.sh bin/console make:migration bin/console doctrine:migrations:migrate Patikrinimui su scripts/mysql.sh DESCRIBE symfony.user; Dokumentacija: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html https://symfony.com/doc/master/bundles/DoctrineMigrationsBundle/index.html
Ji bus reikalinga registracijos formos kūrimui (kitu atveju make:registration-form mestų klaidą) Sugeneruota su scripts/backend.sh composer require form validator Dokumentacija: https://symfony.com/doc/current/validation.html
Sugeneruota naudojant scripts/backend.sh bin/console make:registration-form Naudojant atsakymus: Do you want to add a @UniqueEntity validation annotation on your User class to make sure duplicate accounts aren't created? [yes] Do you want to automatically authenticate the user after registration? [no] What route should the user be redirected to after registration? [home] Kol nėra pilnai pabaigas prisijungimas, negalime naudoti "automatically authenticate" funkcionalumo. Po registracijos tiesiog nukreipiame į egzistuojantį route'ą (pagrindinio puslapio adresą). Laukelių suvedimui naudojamos Symfony formos. Sutikimo su sąlygomis laukelis atėjo kartu su GDPR įstatymu (duomenų apsaugos). Patikrinimui naršyklėje: http://127.0.0.1:8000/register Patikrinimui per scripts/mysql.sh SELECT * FROM symfony.user; Dokumentacija: https://symfony.com/doc/current/doctrine/registration_form.html https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html https://symfony.com/doc/current/forms.html https://gdpr-info.eu/
Jau turėjome naudotojo klasę ir registraciją – trūko tik pačio prisijungimo. Kodas sugeneruotas su scripts/backend.sh bin/console make:auth Pasirinkti atsakymai: What style of authentication do you want? [1] The class name of the authenticator to create [AppCustomAuthenticator] Choose a name for the controller class [SecurityController] Do you want to generate a '/logout' URL? (yes/no) [yes] Yra sukuriama forma http://127.0.0.1:8000/login adresu, bet bandant prisjungti reikalauja pakeitimų: TODO: provide a valid redirect inside /code/src/Security/AppCustomAuthenticator.php Dokumentacija: https://symfony.com/doc/current/security/form_login_setup https://symfony.com/doc/current/security/guard_authentication.html#step-3-configure-the-authenticator
Nukreipiame prisjungusį naudotoją į pagrindinį puslapį. Survarkome eilutes, kad atitiktų kodo stilių. Prisijungimas veikia, bet nėra nei Atsijungti mygtuko, nei automatinio prisjungimo po registracijos. Dokumentacija: https://symfony.com/doc/current/security/form_login_setup#finishing-the-login-form
Twig šablonose yra specialus kintamasis "app", kurio vienas iš elementų ir yra "user". Kai nėra prisijungta – "app.user" yra null. Kai prisijungiama, Symfony pakeičia kintamąjį į konkretų naudotoją. Twige getter'iai pasiekiami ir bet get žodelio (pvz. $user->getUserName -> user.username, $user->getRoles -> user.roles) Užmiršus, kokie adresai naudojami, pasitikrinti galima per scripts/backend.sh bin/console debug:route Dokumentacija: https://symfony.com/doc/master/templating/app_variable.html http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserInterface.html https://getbootstrap.com/docs/4.0/components/navbar/
Patogu, jei norima nukreipti į Prisijungimą arba neužtenka standartinių Security konfiguracijos galimybių. Naudotojo objektas įdedamas į kontrolerio metodą (analogiškai kaip Service'ams). Alternatyva būtų naudoti "$this->getUser()", bet naudojant per argumentus – lengviau bus perkeleti į kitą projektą (ar paruošti testams). Nors pavyzdžiuose yra Security $security, $security->getUser(), bet praktikoje kitos funkcijos (credentials, attributes) rečiau naudojamas nei tiesiogiai kviečiamas UserInterface. Jei naudotojas(-a) neprisijungęs, reikia "UserInterface $user = null", kitaip Symfony nežinos ką daryti su null (neprisijungęs), kurio negalima paversti į UserInterface objektą. Pastaba: AccessDeniedException yra standartinis atsakymas, kai neprisiregistruojama, bet tada grąžinas HTTP 500 statusas. Produkcinėje aplinkoje reikėtų reaguoti į kernel.exception arba užsidėti templates/bundles/TwigBundle/Exception/error.html.twig žmogiškai klaidos žinutei Dokumentacija: https://symfony.com/doc/current/security.html#b-fetching-the-user-from-a-service https://symfony.com/doc/current/controller.html#redirecting https://symfony.com/blog/new-in-symfony-3-2-user-value-resolver-for-controllers https://symfony.com/doc/current/security.html#securing-controllers-and-other-code
Sugeneruota su scripts/backend.sh composer require admin easycorp/easyadmin-bundle yra oficialiai siūlomas Symfony kūrėjų. Taigi galima tikėtis geresnio suderinamumo su Symfony karkasu. Nors ir yra sukuriamas kelias (route): ./bin/console debug:route easyadmin Vis tiek išmes klaidos pranešimą, nes nenurodėme, ką administruoti: The backend is empty because you haven't configured any Doctrine entity to manage Dokumentacija: https://symfony.com/doc/master/bundles/EasyAdminBundle/book/installation.html https://github.com/EasyCorp/EasyAdminBundle https://packagist.org/packages/easycorp/easyadmin-bundle https://symfony.com/doc/current/translation.html
Per naršyklę atidarius: http://127.0.0.1:8000/admin/ Jau kažką rodo, bet dar yra daug kas, ką reikėtų tobulinti (neatpažįsta prisijungusio naudotojo, pasiekiamas visų, nėra visų laukų). Dokumentacija: https://symfony.com/doc/master/bundles/EasyAdminBundle/book/your-first-backend.html
Nes negerai, kad kiekvienas žmogus galėtų redaguoti/matyti visus registruotus naudotojus. Tai nėra visiškai saugu! Bet kol mokomės tokiu būdu galima lengvai patestuoti. Ir tai yra geras būdas suvokti "access_control" veikimą. Patikrinimui: Neprisijungus ir į http://127.0.0.1:8000/admin/ nukreipia į kitą puslapį Prisjungus rodo normaliai. Abejojant dėl konfiguracijos, galima ją pasitikrinti su scripts/backend.sh bin/console config:dump-reference security access_control bin/console debug:config security access_control Abejojant dėl nuorodų, galima ją pasitikrinti su scripts/backend.sh bin/console debug:route Dokumentacija: https://symfony.com/doc/current/security/access_control.html
Ją naudosime pasikeisti administratoriaus rolei. Daroma prielaida, kad prisijungimas prie serverio yra labiau apsaugotas nei naršyklė ir tai yra intuityviau nei keisti kažką per duomenų bazę. Sugeneruota per scripts/backend.sh bin/console make:command app:promote-user Patikrinimui per scripts/backend.sh bin/console list app bin/console app:promote-user Dokumentacija: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html https://symfony.com/doc/current/components/console.html
Per komandinę eilutę pridedame ROLE_ADMIN rolę registruotam naudotojui – taip apsaugome administravimo panelę nuo įsilaužėlių. UserRepository klasėje pasidarome papildomą metodą, kad būtų patogiau ieškoti elemento (duomenų bazės įžanga). Patikrinimui per scripts/backend.sh bin/console app:promote-user --help bin/console app:promote-user aurelijus@banelis.lt Ir tada bandome užeiti į http://127.0.0.1:8000/admin Pakeitus rolę – gali reikėti iš naujo prisijungti, nes naudotojo pasikeitimas tikrinamas pagal serialize metodą su išsaugota versija Sesijoje. Dokumentacija: https://symfony.com/doc/current/components/console.html https://symfony.com/doc/3.4/doctrine/repository.html https://symfony.com/doc/current/security.html#roles https://symfony.com/doc/current/security/user_provider.html#understanding-how-users-are-refreshed-from-the-session
Jei prisjungtume naudotoju, kuris turi ne tą rolę, Symfony duoda 403 Forbidden klaidą. Jei naudotojas iš viso nėra prisijungęs – Symfony yra pakankamai protingas, kad nukreiptų į prisijungimo adresą. Kadangi jau yra gražus šablonas, tai galima naudoti AccessDeniedException klaidą, kuri sugeneruos 403 klaidos puslapį. Kai APP_ENV=dev (paleidus scripts/install-dev.sh) atvaizdavimą šablonas matomas per: http://127.0.0.1:8000/_error/403.html Kai APP_ENV=prod (paleidus scripts/install-prod.sh) ši klaida bus rodoma per: http://127.0.0.1:8000/admin/ Kai naudotojas yra prisijungęs, bet neturi ROLE_ADMIN teisių Dokumentacija: https://symfony.com/doc/current/controller/error_pages.html https://symfony.com/doc/current/bundles/override.html#templates
Per Profiler Toolbar -> Twig -> Rendering Call Graph randame mus domintančią dalį. Per Profiler Toolbar -> Configuration -> Enabled Bundles randame Bundle pavadinimą ir atitikmenį failų sistemoje. Nukopijuojame turinį į templates/bundles/BUNDLE_PAVADINIMAS/ORIGINAL_ADRESAS Atkreipkite dėmesį, kad pavadinimas gali būti EasyAdminBundle, o ne EasyAdmin! Jei nepasikeičia, gali prireikti: bin/console cache:clear Dokumentacija: https://symfony.com/doc/current/bundles/override.html#templates
Pritaikome layout.html.twig šabloną, kad jis naudotų mūsų projekto base.html.twig tėvinį šabloną. Reikia daryti atsargiai, nes lengva pralesiti kokią nors CSS/JavaScript dalį ir biblioteka nebeveiks. Dokumentacija: https://symfony.com/doc/current/bundles/override.html#templates https://twig.symfony.com/doc/3.x/tags/extends.html
Kitų rašytos bibliotekos turi savo dokumentaciją, todėl norint jas pritaikyti savo reikmėms, reikia eiti per jų dokumentaciją, tikrinti su Profiler toolbar, xDebug ir pan. Šiame pavyzdyje skirtingai atvaizduojamos rolės (templates parametras). Naudojamas formos tipas rolėms (type parametras). Slaptažodžio įrašymui naudojami virtualūs metodai (reikšmės apsaičiuojamos, bet neįrašomos į duomenų bazę – įrašymui išskaičiuojama iš kitų laukų). Dokumentacija: https://symfony.com/doc/master/bundles/EasyAdminBundle/book/list-search-show-configuration.html#customize-the-properties-displayed https://symfony.com/doc/master/bundles/EasyAdminBundle/book/edit-new-configuration.html#virtual-properties https://symfony.com/doc/current/reference/forms/types.html https://symfony.com/doc/current/reference/forms/types/collection.html
Kadangi registracijos puslapis naudoja Symfony form, todėl galima vienoje vietoje nustatyti šabloną ir visos iki tol naudotos formos gaus gražesnį (telefonams tinkamesnį) dizainą. Patikrinimui: http://127.0.0.1:8000/register Dokumentacija: https://symfony.com/doc/current/form/bootstrap4.html https://symfony.com/doc/current/forms.html
Jei norime, kad naudotojas turėtų daugiau informacijos, reikia pridėti papildomus laukus į Entity kalsę. PHPStorm turi gerą funkciją sugeneruoti Getter'ius ir Setter'ius (jie bus naudojami Twig'e ir AdminBundle) Šioje stadijoje duomenų modelis ir duomenų bazė gali skirtis, todėl galima pamatyti klaidų: An exception occurred while executing 'SELECT SQLSTATE[42S22]: Column not found Tą pataisysime sekančiame žingsnyje Dokumentacija: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/cookbook/working-with-datetime.html https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/annotations-reference.html#column
Naujiems laukams reikia naujų stulpelių duomenų bazės lentelėse. Symfony turi MigrationBundle, kuris gali sugeneruoti migraciją (SQL užklausas) pagal Entity ir dabartinės duomenų bazės skirtumą. Sugeneravimui naudojama dabartinė data ir reikšmė "migration_versions", todėl atkrartojant skirtinga tvarka gali nesuveikti (daroma prielaida, kad migracijos yra sukurtos pagal datą viena po kitos). Sugeneruota naudojant scripts/backend.sh bin/console doctrine:migrations:diff Duomenų bazė atnaujinta naudojant scripts/backend.sh bin/console doctrine:migrations:migrate Dokumentacija: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/cookbook/working-with-datetime.html
Symfony naudoja formas, kad būtų galima sugeneruoti visus patirkinimus (validacijas) daug paprasčiau. Twig'e visi getter'iai veikia ir be "get" dalies (getHomepage -> homepage) Kadangi pridedame naują lauką – tai naudojame NULL senoms duomenų bazės eilutėms. Standartiškai visi formos laukai yra privalomi – tai pakeičiame, kad svetainės adresas būtų nebūtinas. Dokumentacija: https://symfony.com/doc/current/forms.html https://symfony.com/doc/current/reference/forms/types/form.html#required
Vietoj nukreipimo į kitą puslapį, iškviečiame prisjungimui naudotą klasę. Patikrinimui: Po registracijos http://127.0.0.1:8000/register turėtų rodyti jau naujai prisjungusį naudotoją Dokumentacija: https://symfony.com/doc/current/security/guard_authentication.html#manually-authenticating-a-user
Jei nenurodomas slaptažodis – forma duoda NULL reikšmę ir nesutampa tipai. Be to praktikoje naudotojų slaptažodžiai administratoriui nėra žinomi, ir dažniau keičiami kiti laukai. Patirkinimui: Pakeisti naudotją per EasyAdmin ir išsaugoti pakeitimus neužpildžius slaptažodžio.
Kadangi pakeičiami atskirų laukų tipai/savybės, todėl reikia išvardyti visus naudojamus laukus. Pridedant lauką irgi verta naudoti jį labiausiai atitinkantį tipą Dokumentacija: https://symfony.com/doc/current/reference/forms/types.html https://symfony.com/doc/master/bundles/EasyAdminBundle/book/list-search-show-configuration.html#property-types-defined-by-easyadmin
Kitus komponentus (angl. bundles) galima praplėsti ne tik perrašant jų dalis, bet ir įterpiant savo funckionalumą tem skirtose vietose. Pvz. EasyAdmin bundle yra palikęs vietas praplėtimui prieš ir po įrašų kūrimo/redagivmo/trynimo. Tokiu būdu galima plabai švariai papildyti esamą funkcionalumą Patogumui – MakerBundle turi generatorių tokiems praplėtimams Kodas sugeneruotas su scripts/backend.sh bin/console make:subscriber EasyAdminSubscriber easy_admin.pre_update Dokumentacija: https://symfony.com/doc/master/bundles/EasyAdminBundle/book/complex-dynamic-backends.html#customization-based-on-symfony-events https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html https://symfony.com/doc/current/event_dispatcher.html https://github.com/EasyCorp/EasyAdminBundle/blob/master/src/Event/EasyAdminEvents.php#L48 https://github.com/EasyCorp/EasyAdminBundle/blob/master/src/Controller/AdminControllerTrait.php#L212
Vien sukurti klasę neužtenka, reikia pasakyti Symfony karkasui (per konfiguraciją), kad šita klasę reikia iškviesti. Tam naudojami Service. Tag'ai nurodo karkasui kaip interpretuoti klasę (kada ir kokius metodus iškviesti). "my.easy_admin.pre_edit.subscrubier" yra bet koks sugalvotas pavadinimas. Symfony yra protingas ir su "autowire: true" pagal funkcijų argumentų tipus gali sudėlioti atitinkama reikšmes. Patikrinimui: Pabandome pakeisti naudotoją per http://127.0.0.1:8000/admin/ Turėtų parodyti, ką gauname į Event'o argumentą. Dirbant su EventSubscriberInterface, praverčia xDebug žinios. Dokumentacija: https://symfony.com/doc/current/event_dispatcher.html https://knpuniversity.com/screencast/fosuserbundle/customize-events https://github.com/EasyCorp/EasyAdminBundle/blob/master/src/Event/EasyAdminEvents.php#L48 https://github.com/EasyCorp/EasyAdminBundle/blob/master/src/Controller/AdminControllerTrait.php#L212 https://symfony.com/doc/current/logging.html
Event'as yra iššaukiamas prieš rašant į duomenų bazę. Kaip argumentas paduodamas User objektas ir EntityManager. Mes norime pakeisti datą, tik jei buvo panaudotas setPlainPassword metodas. Glaliausiai viską gražiai atvaizduojame, pakeisdami password atvaizdavimo šabloną Patkrinimui: Pakeitus slaptažodį per http://127.0.0.1:8000/admin/ Turėtų slaptažodžio laukelyje rodyti pakeitimo datą Dokumentacija: https://twig.symfony.com/doc/2.x/filters/date.html https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber https://symfony.com/doc/master/bundles/EasyAdminBundle/book/complex-dynamic-backends.html#event-subscriber-example # Conflicts: # src/Entity/User.php # src/EventSubscriber/EasyAdminSubscriber.php
Naudotojo modelį apsirašėme kaip Entity klasę, bet vis tiek reikia, kad duomenų bazėje būtų atitinkamos lentelės. Sugeneruota su scripts/backend.sh bin/console doctrine:migrations:diff Duomenų bazės atnaujinimui su scripts/backend.sh bin/console doctrine:migrations:migrate Patikrinimui su scripts/mysql.sh DESCRIBE symfony.user; Dokumentacija: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html https://symfony.com/doc/master/bundles/DoctrineMigrationsBundle/index.html
Merge remote-tracking branch 'indre/symfony-namu-darbas-3' into indre-sf-hw3 Conflicts: config/packages/easy_admin.yaml src/Entity/User.php src/Form/RegistrationFormType.php templates/base.html.twig templates/registration/register.html.twig templates/security/profile.html.twig
Owner
Author
|
Realiame projekte, |
Owner
Author
|
Savišvietai apie git'ą: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Rebased: #278