Se stai chiedendo "Cos'è Yii?" guarda il mio tutorial precedente: Introduzione al framework Yii, che rivede i vantaggi di Yii e include una panoramica delle novità in Yii 2.0, rilasciata nell'ottobre 2014.
In questa serie di programmazione con Yii2, guido i lettori all'uso del nuovo Yii2 Framework per PHP.
Nella prima parte, abbiamo configurato Yii2 localmente, creato un'applicazione Hello World, configurato un server remoto e utilizzato Github per implementare il nostro codice. Nella seconda parte, abbiamo appreso l'implementazione di Yii della sua architettura Model View Controller e come creare pagine Web e moduli che raccolgono e convalidano i dati.
Nella terza parte, abbiamo utilizzato il database di Yii e le capacità di registrazione attive per automatizzare la generazione di codice per un'applicazione Web di base. Nella quarta parte, abbiamo imparato come integrare la registrazione degli utenti. E nella parte cinque, abbiamo esplorato la localizzazione con I18n per preparare la tua applicazione agli utenti globali.
In questo tutorial, ti mostrerò come implementare i controlli di accesso per garantire che solo gli utenti giusti possano accedere alle parti della nostra applicazione che desideriamo possano.
Per questi esempi, continueremo a immaginare che stiamo costruendo un framework per la pubblicazione di semplici aggiornamenti di stato, ad es. il nostro mini-Twitter.
Solo un promemoria, parteciperò alle discussioni dei commenti qui sotto. Sono particolarmente interessato se hai approcci diversi, idee aggiuntive o vuoi suggerire argomenti per futuri tutorial.
Il controllo degli accessi si integra con le funzioni di autenticazione del framework per consentire o limitare l'accesso a funzioni o pagine specifiche del tuo sito web.
Il codice che abbiamo scritto finora consente a chiunque di creare post anche se non hanno effettuato l'accesso. Ad esempio, nella nostra applicazione di esempio, puoi visitare la pagina Stato e pubblicare elementi senza accedere.
Possiamo utilizzare le semplici funzionalità di controllo degli accessi di Yii2 per garantire che gli utenti si registrino e accedano prima di aggiungere e visualizzare i post di stato.
Yii2 offre anche un RBAC (Role Based Access Control) più avanzato (e complesso) che non implementeremo in questo momento. Con RBAC, si definisce una sofisticata gerarchia di autorizzazioni per ogni possibile attività all'interno della propria applicazione.
Il controllo accessi integrato di Yii2 supporta solo due ruoli per impostazione predefinita: guest (non connesso), rappresentato da "?" E autenticato, rappresentato da "@". Con semplici controlli di accesso, possiamo limitare l'accesso a pagine specifiche o azioni del controllore in base allo stato di accesso. Se gli utenti non effettuano l'accesso quando visitano le pagine dei luoghi, Yii li reindirizzerà alla pagina di accesso.
In questo tutorial, ti introdurrò a utilizzare i controlli di accesso semplici di Yii2 per la nostra applicazione di esempio. Quindi estenderemo l'accesso semplice con ruoli aggiuntivi come moderatore e amministratore.
Attualmente, la nostra applicazione consente l'accesso a StatusController anche senza effettuare l'accesso. Risolviamolo.
Il framework rende abbastanza semplice l'implementazione di questi controlli. Aggiungiamo solo comportamenti a StatusController.php che definiscono le regole di accesso per ogni azione, ad es. indice, creare, visualizzare, ecc.
Qui esamineremo il comportamento di accesso, ma se sei interessato, i filtri verbo di Yii ti consentono di limitare le operazioni di richiesta http in base all'azione del tuo controller.
public function behaviors () return ['verbs' => ['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post'],],], 'accesso' => ['class' => \ yii \ filters \ AccessControl :: className (), 'only' => ['index', 'create', 'update', 'view'], 'rules' => [/ / consenti utenti autenticati ['allow' => true, 'roles' => ['@'],], // tutto il resto è negato],],];
Una volta aggiunto, se si fa clic sul Stato menu, verrai reindirizzato alla pagina di accesso:
Yii gestisce anche il reindirizzamento alla pagina dell'indice di stato una volta che il login è completo.
Ora, quando gli utenti accedono alle pagine di stato, possiamo trovare l'utente corrente con questo codice:
Yii :: $ app-> user-> getId ();
E possiamo associare i post di stato al loro creatore nel modello.
Per fare ciò, dobbiamo estendere la tabella dello stato con una nuova migrazione della tabella:
./ yii migrate / create extend_status_table_for_created_by Yii Strumento di migrazione (basato su Yii v2.0.1) Crea nuova migrazione '/Users/Jeff/Sites/hello/migrations/m150128_003709_extend_status_table_for_created_by.php'? (sì | no) [no]: sì Nuova migrazione creata con successo.
Ecco il codice di migrazione che aggiunge una colonna per creato da
. Aggiungiamo anche una chiave esterna per creare una relazione tra il Visualizzazione di stato> CREATED_BY
campo e il User-> id
tavolo.
db-> driverName === 'mysql') $ tableOptions = 'SET CARATTERE utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'; $ this-> addColumn ('% status', 'created_by', Schema :: TYPE_INTEGER. 'NOT NULL'); $ this-> addForeignKey ('fk_status_created_by', '% status', 'created_by', '% user', 'id', 'CASCADE', 'CASCADE'); public function down () $ this-> dropForeignKey ('fk_status_created_by', '% status'); $ This-> dropColumn ( 'status%', 'created_by');
Eseguiamo la migrazione:
./ yii migrate / up Yii Migration Tool (basato su Yii v2.0.1) Totale 1 nuova migrazione da applicare: m150128_003709_extend_status_table_for_created_by Applicare la migrazione sopra? (sì | no) [no]: sì *** applicando m150128_003709_extend_status_table_for_created_by> aggiungi colonna created_by intero NOT NULL alla tabella % status ... done (time: 0.009s)> aggiungi chiave esterna fk_status_created_by: % status (created_by) reference % user (id) ... done (time: 0.007s) *** applicato m150128_003709_extend_status_table_for_created_by (time: 0.020s) Migrato con successo.
Ho rieseguito la generazione del codice Gii con la nuova tabella di stato e ho copiato e incollato i nuovi elementi aggiuntivi. La maggior parte erano minori ma noterete che aggiunge una nuova ActiveQuery per la relazione:
/ ** * @return \ yii \ db \ ActiveQuery * / public function getCreatedBy () return $ this-> hasOne (User :: className (), ['id' => 'created_by']);
Quindi, appena prima che i nuovi elementi di stato vengano salvati, possiamo aggiornare il file creato da
campo all'utente attualmente connesso. E possiamo fidarci dei controlli di accesso per garantire il creare
metodo è accessibile solo da utenti autenticati:
funzione pubblica actionCreate () $ model = new Status (); if ($ model-> load (Yii :: $ app-> request-> post ())) $ model-> created_by = Yii :: $ app-> user-> getId (); $ model-> created_at = time (); $ model-> updated_at = time (); if ($ model-> save ()) return $ this-> redirect (['view', 'id' => $ model-> id]); restituisce $ this-> render ('create', ['model' => $ model,]);
Estenderemo anche il widget vista per includere il creato da
campo:
= DetailView::widget([ 'model' => $ model, 'attributes' => ['id', 'message: ntext', 'created_by', 'permissions', 'created_at', 'updated_at',],])?>
Possiamo anche usare il creato da
relazione per visualizzare l'indirizzo email:
= DetailView::widget([ 'model' => $ model, 'attributes' => ['id', 'createdBy.email', 'message: ntext', 'permissions', 'created_at', 'updated_at',],])?>
Il createdBy.email
accede al Stato :: getCreatedBy
metodo di relazione. Questo visualizza l'indirizzo email dell'utente:
Tuttavia, per supportare questa funzionalità con l'estensione utente Yii2 implementata nella parte quattro, abbiamo dovuto effettuare due modifiche. Innanzitutto, nel nostro app \ config \ web.php
array di configurazione, abbiamo aggiunto un override del modello a app \ modelli \ User.php
:
... 'user' => ['class' => 'dektrium \ user \ Module', 'enableUnconfirmedLogin' => true, 'confirmWithin' => 21600, 'cost' => 12, 'modelMap' => ['Utente' => 'app \ models \ User',], 'admins' => ['admin']],
Abbiamo anche creato questo modello in app \ modelli
:
namespace app\models; use dektrium\user\models\User as BaseUser; class User extends BaseUser public function register() // do your magic ?>
Queste due modifiche hanno fornito supporto per la relazione.
Cosa succederebbe se volessimo avere capacità aggiuntive attorno alle azioni del controller? Ad esempio, cosa succede se vogliamo limitare le operazioni di eliminazione a moderatori o amministratori? Il semplice controllo degli accessi di Yii2 non ha un concetto di moderatore o amministratore a meno che non ne crei uno con RBAC.
Si noti che l'estensione utente Yii2 ha un identificatore amministratore per utenti specifici, ma manca anche la flessibilità per ruoli aggiuntivi.
Il Code Ninja ha scritto un bell'esempio di estensione dei controlli di accesso semplici per supportare moderatori e amministratori (semplificazione dell'autorizzazione basata sui ruoli in Yii 2.0) senza dover ricorrere all'utilizzo di RBAC. Il loro esempio funziona con il modello di applicazione avanzato Yii2.
La nostra applicazione è diversa in quanto stiamo utilizzando il modello di applicazione di base di Yii e stiamo usando l'estensione Yii2-user. Pertanto, ho apportato alcune modifiche alla loro guida:
In primo luogo, creiamo un app \ componenti
directory ed e un AccessRule.php
file che estende il built-in di Yii AccessRule
modello:
ruoli)) return true; foreach ($ this-> ruoli come $ role) if ($ role == '?') if ($ user-> getIsGuest ()) return true; elseif ($ role == User :: ROLE_USER) if (! $ user-> getIsGuest ()) return true; // Controlla se l'utente ha effettuato l'accesso e i ruoli corrispondono a else else (! $ User-> getIsGuest () && $ role == $ user-> identity-> role) return true; return false;
Quindi, aggiungiamo definizioni di ruolo alle nostre app \ modelli \ User
modello:
namespace app\models; use dektrium\user\models\User as BaseUser; class User extends BaseUser const ROLE_USER = 10; const ROLE_MODERATOR = 20; const ROLE_ADMIN = 30;
Yii2-utente
non implementa la colonna del ruolo durante la creazione di nuovi utenti. Quindi è possibile specificare manualmente i ruoli per moderatori e amministratori in MySQL o successivamente creare la propria interfaccia utente Web per la concessione dei ruoli.
Nel vendor \ dektrium \ yii2-utente \ modelli \ RegistrationForm.php
, Ho aggiunto questa riga per definire il ruolo utente per gli utenti predefiniti:
Nota: dovrai apportare questa modifica manualmente se lo desideri perché la directory del mio fornitore non viene registrata nel nostro albero GitHub, e sì, probabilmente c'è un modo più elegante per farlo nella base di codice principale dopo la registrazione , per esempio estendi il metodo createUser in app / models / User.php. La migliore pratica potrebbe essere quella di imporre il repository del fornitore e portarlo nella propria struttura del codice.
** * Registra un nuovo account utente. * @return bool * / public function register () if ($ this-> validate ()) $ user = $ this-> module-> manager-> createUser (['scenario' => 'register', 'email '=> $ this-> email,' username '=> $ this-> username,' password '=> $ this-> password,' role '=> 10, // User :: ROLE_USER;]); return $ user-> register (); return false;
Finalmente, in StatusController.php
, aggiungiamo alcune librerie e queste definizioni di accesso. Nell'esempio seguente, le azioni di aggiornamento sono riservate ai moderatori e le azioni di eliminazione sono riservate agli amministratori.
['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post'],],], 'access' => ['class' => AccessControl :: className ( ), // Sostituiremo la configurazione della regola predefinita con la nuova classe AccessRule 'ruleConfig' => ['class' => AccessRule :: className (),], 'only' => ['index', 'create', 'update', 'delete'], 'rules' => [['actions' => ['index', 'create'], 'allow' => true, // Permetti agli utenti, moderatori e amministratori di creare 'ruoli '=> [Utente :: ROLE_USER, Utente :: ROLE_MODERATOR, Utente :: ROLE_ADMIN],], [' actions '=> [' update '],' allow '=> true, // Consenti ai moderatori e agli amministratori di aggiornare' roles '=> [Utente :: ROLE_MODERATOR, Utente :: ROLE_ADMIN],], [' actions '=> [' elimina '],' allow '=> true, // Permetti agli amministratori di cancellare' ruoli '=> [Utente :: ROLE_ADMIN],],],],];
Ora, quando esci e visita il Stato pagina dalla barra di navigazione, verrai indirizzato alla schermata di accesso:
Quando accedi, verrai nuovamente indirizzato alla vista indice:
Tuttavia, se clicco Elimina, Otterrò questo errore di accesso vietato perché sono un utente modesto, non un amministratore:
Se vuoi elevarti all'amministratore, puoi farlo nel database, cambiando la colonna del ruolo della tabella User per user_id a 20 per moderatore e 30 per admin. Prova nuovamente l'aggiornamento e cancella le operazioni e sarai autorizzato in base al ruolo scelto.
I controlli di accesso sono una delle molte caratteristiche che mi rendono un grande sostenitore dell'uso di Yii Framework. Yii mi rende uno sviluppatore molto più efficiente, in grado di fornire soluzioni molto più rapidamente di quanto possa fare con vanilla PHP.
Guarda le prossime esercitazioni nella mia serie Programming with Yii2 mentre continuo a immergermi nei diversi aspetti del framework. Potresti anche voler controllare la mia creazione della tua startup con la serie PHP, che usa il template avanzato di Yii2 mentre costruisco un'applicazione del mondo reale.
Se vuoi sapere quando arriverà il prossimo tutorial di Yii2, seguimi @reifman su Twitter o controlla la mia pagina di istruttore. La mia pagina di istruttore includerà tutti gli articoli di questa serie non appena saranno pubblicati. Puoi anche mandarmi una e-mail sul mio sito Web di Lookahead Consulting.