Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Caricare gli utenti dal database

Modificare il sistema di login di un'applicazione basata sul framework Symfony affinché carichi gli utenti dal database anziché in memoria
Modificare il sistema di login di un'applicazione basata sul framework Symfony affinché carichi gli utenti dal database anziché in memoria
Link copiato negli appunti

Ora che abbiamo connesso la nostra applicazione al database, possiamo modificare il sistema di login affinché carichi gli utenti dal database anziché in memoria.

Prima di procedere è necessario aggiornare Symfony all’ultima versione disponibile, così da avere anche l’applicazione aggiornata. Vi basta spostarvi sul tag bump-symfony-5.2 e lanciare un composer install. Se si dovesse verificare qualche problema di conflitti provate a cancellare la cartella vendor per poi riprovare.

Creazione entità

Il primo passo per modificare il sistema di login consiste nella creazione dell’Entità su cui mapperemo l’utente. Abbiamo già visto cos’è un’entità quando abbiamo introdotto Doctrine e la libreria di ORM. Andiamo quindi a creare la classe PHP e le relative configurazioni che consentiranno a Doctrine di mappare la tabella user sul database con l’entità App\Entity\User.

Non sarà un lavoro molto lungo la creazione dell’entità, molto del lavoro lo farà la linea di comando.

All’interno del container, quindi, lanciamo il comando ./bin/console make:user che, come possiamo immaginare dal nome, aprirà il wizard con cui creare la nostra entità User. La maggior parte delle impostazioni di default non dovranno esser modificate, limitiamoci quindi a dire al sistema che utilizzeremo la e-mail come campo “display”. Di seguito l’output completo:

$ ./bin/console make:user
 The name of the security user class (e.g. User) [User]:
 >
 Do you want to store user data in the database (via Doctrine)? (yes/no) [yes]:
 >
 Enter a property name that will be the unique "display" name for the user (e.g. email, username, uuid) [email]:
 > email
 Will this app need to hash/check user passwords? Choose No if passwords are not needed or will be checked/hashed by some other system (e.g. a single sign-on server).
 Does this app need to hash/check user passwords? (yes/no) [yes]:
 >
 created: src/Entity/User.php
 created: src/Repository/UserRepository.php
 updated: src/Entity/User.php
 updated: config/packages/security.yaml
  Success!
 Next Steps:
   - Review your new App\Entity\User class.
   - Use make:entity to add more fields to your User entity and then run make:migration.
   - Create a way to authenticate! See https://symfony.com/doc/current/security.html

Come anche il comando ci suggerisce, sono stati generati due nuovi file ed aggiornato il file security.yaml.

Dando un veloce sguardo all’entità appena creata (app/src/Entity/User.php) noteremo che non è solo una semplice classe PHP ma che contiene anche diverse annotazioni. Come per il Repository, tratteremo queste annotazioni in una lezione dedicata, per ora è importante sapere che sono le configurazioni necessarie a Doctrine per associare l’entità alla tabella sul database.

L’altro file creato (src/Repository/UserRepository.php) è il repository della nostra entità. Introdurremo in una delle prossime lezioni il concetto di Repository, mentre per il momento ci è sufficiente sapere, in questa fase, che sarà la classe che ci permetterà di effettuare query al database per l’utente.

Il security.yaml, invece, è stato modificato per aggiungere:

  • un nuovo encoder: serve ad indicare quale meccanismo di encoding verrà utilizzato per generare l’hash della password;
  • è stato sostituito il provider in memory con uno che contiene utilizza la nuova entità.

Dopo aver apportato queste modifiche il precedente sistema di login non funzionerà più. Se abbiamo una sessione ancora attiva effettuiamo il logout per evitare di ricevere errori: http://kvak.local/logout.

Creazione ed esecuzione della migrazione

Come suggerito nell’output del comando make:user, dobbiamo creare la tabella user nel database. Per fare ciò abbiamo bisogno di affrontare due step.

Creare una migrazione

Una migrazione un file PHP che contiene le query che andranno a modificare il database per allinearlo alle modifiche che abbiamo effettuato sull’applicazione. È molto utile utilizzare le migrazioni per tenere il database allineato anche in fase di deploy senza la necessità di eseguire delle query manualmente, riducendo nel contempo in modo notevole la possibilità di un errore umano.

Lanciamo quindi il comando come di seguito:

$ ./bin/console make:migration
  Success!
 Next: Review the new migration "migrations/Version20210220161856.php"
 Then: Run the migration with php bin/console doctrine:migrations:migrate
 See https://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html

Se apriamo il file appena creato (migrations/Version20210220161856.php) noteremo che continue due metodi: uno con una query che crea la tabella utente e uno che la droppa.

Questo perché le migrazioni possono essere eseguite ma anche rimosse dal database. Immaginiamo per esempio cosa succederebbe quando qualcosa va storto e si deve effettuare il rollback dell’applicazione ad una situazione precedente a quella del deploy.

Lanceremo questo comando ogni volta che aggiungeremo o rimuoveremo tabelle e/o campi dal database. Non interverremo mai manualmente sul database.

Eseguire la migrazione nel nostro database locale

una volta creato il file che contiene le query, possiamo lanciare un altro comando che applica le migrazioni mancanti:

$ php bin/console doctrine:migrations:migrate
 WARNING! You are about to execute a migration in database "kvak" that could result in schema changes and data loss. Are you sure you wish to continue? (yes/no) [yes]:
 > yes
[notice] Migrating up to DoctrineMigrations\Version20210220161856
[notice] finished in 148.7ms, used 18M memory, 1 migrations executed, 1 sql queries

Accedendo al database dopo questa operazione noteremo che abbiamo due tabelle:

  • user che contiene 4 campi: id, email, roles, password.
  • doctrine_migration_versions che contiene le migrazioni finora applicate. Nel nostro caso solo una.

Caricamento dati di prova

Ora che abbiamo la tabella utenti nel database possiamo creare qualche utente di prova con cui effettuare il login. Per fare questo creeremo delle fixtures, ovvero un set di dati pre-esistente con cui possiamo popolare l’applicazione in ogni momento. Per fare questo abbiamo bisogno di aggiungere una nuova ricetta:

$ composer require orm-fixtures --dev

Al termine dell’operazione oltre ad avere i vari file di composer e Symfony Flex modificati, troveremo anche un nuovo file app/src/DataFixtures/AppFixtures.php. All’interno di questo file creeremo due utenti che useremo per popolare il database:

class AppFixtures extends Fixture
{
    /** @var UserPasswordEncoderInterface */
    private $passwordEncoder;  
    public function __construct(UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->passwordEncoder = $passwordEncoder;
    }
    public function load(ObjectManager $manager)
    {
        $ryan = new User();
        $ryan->setEmail('ryan@ryan.it');
        $ryan->setPassword($this->passwordEncoder->encodePassword($ryan, 'helloworld'));  
        $julie = new User();
        $julie->setEmail('julie@julie.it');
        $julie->setPassword($this->passwordEncoder->encodePassword($julie, 'helloworld'));  
        $manager->persist($ryan);
        $manager->persist($julie);
        $manager->flush();
     }
 }

Guardando il costruttore noteremo che abbiamo anche iniettato un password encoder, questo per permettere di salvare su database la password cifrata e non in chiaro. Ora possiamo caricare le fixtures sul nostro database con il comando:

www-data@4d191dffa1fb:~/kvak$ ./bin/console doctrine:fixtures:load
 Careful, database "kvak" will be purged. Do you want to continue? (yes/no) [no]:
 > yes
   > purging database
   > loading App\DataFixtures\AppFixtures

Se guardiamo ora sul database avremo i nostri due utenti appena creati! Ci basterà quindi effettuare il login con le credenziali di uno dei due per poter accedere nuovamente all’applicazione.

Tutto il codice è disponibile nel repository con il tag login-from-db.

Come abbiamo potuto notare da questa lezione, sostituire la sorgente di dati da cui caricare gli utenti è stato davvero molto semplice e veloce. L’unico codice necessario è stato quello per la creazione di utenti di prova. Ora che abbiamo gli utenti salvati sul database possiamo procedere a creare anche la pagina di registrazione.


Ti consigliamo anche