In questo articolo, imparerai come configurare l'autenticazione utente in PHP usando il componente Symfony Security. Oltre all'autenticazione, ti mostrerò come utilizzare la sua autorizzazione basata sui ruoli, che puoi estendere in base alle tue esigenze.
Symfony Security Component consente di configurare funzionalità di sicurezza come autenticazione, autorizzazione basata sui ruoli, token CSRF e molto più facilmente. Di fatto, è ulteriormente suddiviso in quattro sottocomponenti che puoi scegliere in base alle tue esigenze.
Il componente Sicurezza presenta le seguenti sottocomponenti:
In questo articolo, esploreremo la funzione di autenticazione fornita da symfony / sicurezza-core componente.
Come al solito, inizieremo con le istruzioni di installazione e configurazione, quindi esamineremo alcuni esempi reali per dimostrare i concetti chiave.
In questa sezione, installeremo il componente Symfony Security. Presumo che tu abbia già installato Composer sul tuo sistema: ne avremo bisogno per installare il componente Security disponibile su Packagist.
Quindi, andare avanti e installare il componente di sicurezza utilizzando il seguente comando.
$ compositore richiede symfony / sicurezza
Nel nostro esempio caricheremo utenti dal database MySQL, quindi avremo anche bisogno di un livello di astrazione del database. Installiamo uno dei più popolari livelli di astrazione del database: Doctrine DBAL.
$ compositore richiede dottrina / dbal
Questo dovrebbe aver creato il composer.json file, che dovrebbe assomigliare a questo:
"require": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7"
Modifichiamo il composer.json file per assomigliare al seguente.
"require": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7", "autoload": "psr-4": "Sfauth \\": "src" , "classmap": ["src"]
Come abbiamo aggiunto un nuovo classmap
voce, andiamo avanti e aggiorniamo il caricatore automatico del compositore eseguendo il seguente comando.
$ compositore discarica -o
Ora puoi usare il Sfauth
spazio dei nomi per le classi di autoload sotto il src elenco.
Quindi questa è la parte di installazione, ma come si dovrebbe utilizzarla? In realtà, è solo questione di includere il autoload.php file creato da Composer nella tua applicazione, come mostrato nello snippet seguente.
Innanzitutto, passiamo attraverso il solito flusso di autenticazione fornito dal componente Symfony Security.
Interfaccia utente
interfaccia.Nel nostro esempio, abbineremo le credenziali dell'utente al database MySQL, quindi dovremo creare il provider utente del database. Creeremo anche il provider di autenticazione del database che gestisce la logica di autenticazione. E infine, creeremo la classe User, che implementa il Interfaccia utente
interfaccia.
In questa sezione creeremo la classe User che rappresenta l'entità utente nel processo di autenticazione.
Vai avanti e crea il src / utente / User.php file con il seguente contenuto.
username = $ username; $ this-> password = $ password; $ this-> roles = $ ruoli; public function getUsername () return $ this-> username; public function getPassword () return $ this-> password; funzione pubblica getRoles () return explode (",", $ this-> roles); public function getSalt () return "; public function eraseCredentials ()
L'importante è che la classe User debba implementare Symfony Security Interfaccia utente
interfaccia. A parte questo, qui non c'è niente fuori dall'ordinario.
È responsabilità del fornitore dell'utente caricare gli utenti dal back-end. In questa sezione creeremo il provider utente del database, che carica l'utente dal database MySQL.
Creiamo il src / utente / DatabaseUserProvider.php file con il seguente contenuto.
connessione = $ connessione; public function loadUserByUsername ($ username) return $ this-> getUser ($ username); funzione privata getUser ($ username) $ sql = "SELECT * FROM sf_users WHERE username =: name"; $ stmt = $ this-> connection-> prepare ($ sql); $ stmt-> bindValue ("nome", $ username); $ Stmt-> execute (); $ row = $ stmt-> fetch (); if (! $ row ['username']) $ exception = new UsernameNotFoundException (sprintf ('Username "% s" non trovato nel database. ", $ row [' username '])); $ Eccezione-> SetUserName ($ username); lanciare $ exception; else return new User ($ row ['username'], $ row ['password'], $ row ['ruoli']); public function refreshUser (UserInterface $ user) if (! $ user instanceof User) throw new UnsupportedUserException (sprintf ('Le istanze di "% s" non sono supportate.', get_class ($ user))); return $ this-> getUser ($ user-> getUsername ()); public function supportsClass ($ class) return 'Sfauth \ User \ User' === $ class;
Il provider utente deve implementare il UserProviderInterface
interfaccia. Stiamo utilizzando il DBAL della dottrina per eseguire le operazioni relative al database. Come abbiamo implementato il UserProviderInterface
interfaccia, dobbiamo implementare il loadUserByUsername
, refreshUser
, e supportsClass
metodi.
Il loadUserByUsername
il metodo dovrebbe caricare l'utente con il nome utente, e questo è fatto nel getUser
metodo. Se l'utente viene trovato, restituiamo il corrispondente Sfauth \ User \ User
oggetto, che implementa il Interfaccia utente
interfaccia.
D'altra parte, il refreshUser
il metodo aggiorna il fornito Utente
oggetto recuperando le ultime informazioni dal database.
E infine, il supportsClass
metodo controlla se il DatabaseUserProvider
il provider supporta la classe utente fornita.
Infine, dobbiamo implementare il provider di autenticazione utente, che definisce la logica di autenticazione: come un utente è autenticato. Nel nostro caso, dobbiamo abbinare le credenziali dell'utente al database MySQL, quindi è necessario definire la logica di autenticazione di conseguenza.
Vai avanti e crea il src / utente / DatabaseAuthenticationProvider.php file con il seguente contenuto.
userProvider = $ userProvider; funzione protetta retrieveUser ($ username, token UsernamePasswordToken $) $ user = $ token-> getUser (); if ($ user instanceof UserInterface) return $ user; prova $ user = $ this-> userProvider-> loadUserByUsername ($ username); if (! $ user instanceof UserInterface) throw new AuthenticationServiceException ('Il provider utente deve restituire un oggetto UserInterface.'); return $ user; catch (UsernameNotFoundException $ e) $ e-> setUsername ($ username); buttare $ e; catch (\ Exception $ e) $ e = new AuthenticationServiceException ($ e-> getMessage (), 0, $ e); $ E-> setToken ($ token); buttare $ e; funzione protetta checkAuthentication (UserInterface $ user, UsernamePasswordToken $ token) $ currentUser = $ token-> getUser (); if ($ currentUser instanceof UserInterface) if ($ currentUser-> getPassword ()! == $ user-> getPassword ()) lancia nuova AuthenticationException ('Le credenziali sono state cambiate da un'altra sessione.'); else $ password = $ token-> getCredentials (); if (vuoto ($ password)) lancia nuova AuthenticationException ('Password non può essere vuota.'); if ($ user-> getPassword ()! = md5 ($ password)) lancia nuova AuthenticationException ('Password non valida.');
Il DatabaseAuthenticationProvider
il provider di autenticazione estende il UserAuthenticationProvider
classe astratta. Quindi, abbiamo bisogno di implementare il retrieveUser
e checkAuthentication
metodi astratti.
Il lavoro del retrieveUser
il metodo è caricare l'utente dal fornitore dell'utente corrispondente. Nel nostro caso, userà il DatabaseUserProvider
user provider per caricare l'utente dal database MySQL.
D'altra parte, il checkAuthentication
metodo esegue i controlli necessari per autenticare l'utente corrente. Tieni presente che ho utilizzato il metodo MD5 per la crittografia della password. Ovviamente, è necessario utilizzare metodi di crittografia più sicuri per archiviare le password degli utenti.
Finora, abbiamo creato tutti gli elementi necessari per l'autenticazione. In questa sezione vedremo come mettere tutto insieme per impostare la funzionalità di autenticazione.
Vai avanti e crea il db_auth.php file e popolarlo con il seguente contenuto.
'mysql: // USERNAME: PASSWORD @ HOSTNAME / DATABASE_NAME'), nuovo \ Doctrine \ DBAL \ Configuration ()); // avvia il nostro utente personalizzato db user $ userProvider = new DatabaseUserProvider ($ doctrineConnection); // useremo UserChecker predefinito, è usato per controllare controlli aggiuntivi come blocco account / scaduto, ecc. // è possibile implementare il proprio implementando l'interfaccia UserCheckerInterface $ userChecker = new UserChecker (); // avvia il nostro provider di autenticazione db personalizzato $ dbProvider = new DatabaseAuthenticationProvider ($ userProvider, $ userChecker, 'frontend'); // init authentication provider manager $ authenticationManager = new AuthenticationProviderManager (array ($ dbProvider)); prova // init un / pw, di solito otterrai questi dalla variabile $ _POST, inviata dall'utente finale $ username = 'admin'; $ password = 'admin'; // get touthenticated token $ unauthenticatedToken = new UsernamePasswordToken ($ username, $ password, 'frontend'); // autenticazione utente e get token autenticato $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken); // abbiamo il token autenticato (l'utente ha effettuato l'accesso ora), può essere memorizzato in una sessione per uso futuro echo $ authenticatedToken; echo "\ n"; catch (AuthenticationException $ e) echo $ e-> getMessage (); echo "\ n";
Richiama il flusso di autenticazione che è stato discusso all'inizio di questo articolo: il codice sopra riportato riflette quella sequenza.
La prima cosa era recuperare le credenziali dell'utente e creare un token non autenticato.
$ unauthenticatedToken = new UsernamePasswordToken ($ username, $ password, 'frontend');
Successivamente, abbiamo passato quel token al gestore di autenticazione per la convalida.
// autenticazione utente e get token autenticato $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken);
Quando viene chiamato il metodo di autenticazione, un sacco di cose stanno accadendo dietro le quinte.
In primo luogo, il gestore autenticazione seleziona un provider di autenticazione appropriato. Nel nostro caso, è il DatabaseAuthenticationProvider
provider di autenticazione, che verrà selezionato per l'autenticazione.
Successivamente, recupera l'utente con il nome utente dal DatabaseUserProvider
fornitore di utenti. Finalmente, il checkAuthentication
metodo esegue i controlli necessari per autenticare la richiesta dell'utente corrente.
Se desideri testare il db_auth.php script, dovrai creare il sf_users
tabella nel tuo database MySQL.
CREATE TABLE 'sf_users' ('id' int (11) NOT NULL AUTO_INCREMENT, 'username' varchar (255) NOT NULL, 'password' varchar (255) NOT NULL, 'ruoli' enum ('registrato', 'moderatore', 'admin') DEFAULT NULL, PRIMARY KEY ('id')) ENGINE = InnoDB; INSERISCI I VALORI "sf_users" (1, "admin", "21232f297a57a5a743894a0e4a801fc3", "admin");
Vai avanti e avvia il db_auth.php script per vedere come va. Al completamento con esito positivo, dovresti ricevere un token autenticato, come mostrato nel seguente snippet.
$ php db_auth.php UsernamePasswordToken (utente = "admin", authenticated = true, roles = "admin")
Una volta che l'utente è autenticato, è possibile memorizzare il token autenticato nella sessione per le richieste successive.
E con questo, abbiamo completato la nostra semplice demo di autenticazione!
Oggi, abbiamo esaminato il componente Symfony Security, che consente di integrare funzionalità di sicurezza nelle applicazioni PHP. Nello specifico, abbiamo discusso la funzione di autenticazione fornita dal sottocomponente symfony / security-core e ti ho mostrato un esempio di come questa funzionalità può essere implementata nella tua app.
Sentiti libero di postare i tuoi pensieri usando il feed qui sotto!