Cum se programează cu Yii2 Controale de acces utilizator

Ce veți crea

Dacă vă întrebați: "Ce este Yii?" verificați tutorialul meu anterior: Introducere în Cadrul Yii, care analizează beneficiile Yii și include o prezentare generală a ceea ce este nou în Yii 2.0, lansat în octombrie 2014.

În acest programare cu seria Yii2, îndrumăm cititorii în folosirea noului model Yii2 Framework for PHP. 

În prima parte, am creat Yii2 la nivel local, am construit o aplicație Hello World, am creat un server de la distanță și am folosit Github să implementeze codul nostru. În partea a doua, am aflat despre implementarea de către Yii a arhitecturii Model View Controller și despre modul de a construi pagini web și formulare care colectează și validează datele. 

În partea a treia, am folosit baza de date a Yii și capacitățile active de înregistrare pentru a automatiza generarea de coduri pentru o aplicație web de bază. În partea a patra, am învățat cum să integrăm înregistrarea utilizatorilor. În partea a cincea, am explorat localizarea cu I18n pentru a vă pregăti aplicația pentru utilizatorii globali. 

În acest tutorial, vă voi arăta cum să implementați controalele de acces pentru a vă asigura că numai utilizatorii potriviți pot accesa părțile aplicației noastre pe care le dorim.

Pentru aceste exemple, vom continua să ne imaginăm că construim un cadru pentru afișarea actualizărilor de stare simple, de ex. propriul mini-Twitter.

Doar un memento, eu particip la comentariile de mai jos. Sunt interesat în special dacă aveți abordări diferite, idei suplimentare sau doriți să sugerați subiecte pentru tutoriale viitoare.

Ce este Controlul accesului?

Controlul accesului integrează caracteristicile de autentificare ale cadrului pentru a permite sau a restricționa accesul la anumite funcții sau pagini ale site-ului dvs. Web. 

Codul pe care l-am scris până acum permite oricui să creeze postări chiar dacă nu s-au conectat. De exemplu, în aplicația noastră de probă, puteți să accesați pagina de stare și să postați articole fără să vă conectați. 

Putem folosi funcțiile simple de control al accesului Yii2 pentru a vă asigura că utilizatorii se înregistrează și se conectează înainte de a adăuga și vizualiza mesajele de stare. 

Yii2 oferă de asemenea un control mai avansat (și complex) de control al accesului bazat pe roluri (RBAC), pe care nu îl vom implementa în acest moment. Cu RBAC, definiți o ierarhie sofisticată de permisiuni pentru fiecare activitate posibilă din cadrul aplicației.

Sistemul de control al accesului construit de Yii2 acceptă în mod implicit numai două roluri: oaspetele (nu este conectat), reprezentat prin '?' Și autentificat, reprezentat prin '@'. Cu controale simple de acces, putem limita accesul la anumite pagini sau acțiuni ale controlerului bazate pe starea de conectare. Dacă utilizatorii nu sunt conectați când vizitează paginile locației, Yii le va redirecționa către pagina de conectare.

În acest tutorial, vă prezint folosirea controalelor simple de acces Yii2 pentru aplicația noastră de probă. Apoi, vom extinde accesul simplu cu roluri suplimentare, cum ar fi moderatorul și administratorul.

Implementarea controalelor simple de acces

În prezent, aplicația noastră permite accesul la StatusController chiar și fără conectare. Să rezolvăm acest lucru.

Cadrul simplifică punerea în aplicare a acestor controale. Doar adăugăm comportamente la StatusController.php care definesc regulile de acces pentru fiecare acțiune, de ex. index, crea, vizualiza, etc. 

Aici vom examina comportamentul de acces, dar dacă sunteți interesat, filtrele de verb Yii vă permit să restricționați operațiile de solicitare http pe baza acțiunii controlerului dvs..

funcțiile publicului () return ['verbs' => ['class' => VerbFilter :: className (), 'actions' => ['delete' => => ['class' => \ yii \ filters \ AccessControl :: className (), 'only' => [' / permite utilizatorilor autentificați ['allow' => true, 'roles' => ['@'],], // orice altceva este respins],],]; 

Odată adăugată, dând clic pe stare , veți fi redirecționat către pagina de conectare:

De asemenea, Yii se ocupă de redirecționarea înapoi la pagina Index de stare odată ce logarea sa terminat.

Adăugarea modelului de proprietate

Acum, când utilizatorii accesează paginile de stare, putem găsi utilizatorul curent cu acest cod:

Yii :: $ app-> user-> getId ();

Și putem asocia posturile de stare cu creatorul lor în model.

Pentru a face acest lucru, trebuie să extindem tabelul de stare cu o nouă migrare a tabelului:

./ yii migrați / creați extens_status_table_for_created_by Instrumentul de migrare Yii (bazat pe Yii v2.0.1) Creați noua migrare '/Users/Jeff/Sites/hello/migrations/m150128_003709_extend_status_table_for_created_by.php'? (da | nu) [no]: da Migrația nouă a fost creată cu succes.

Iată codul de migrare care adaugă o coloană pentru creat de. De asemenea, adăugăm o cheie străină pentru a crea o relație între Status-> created_by câmp și User-> id masa.

db-> driverName === 'mysql') $ tableOptions = 'SETAREA CHARACTERULUI 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');  funcția publică jos () $ this-> dropForeignKey ('fk_status_created_by', '% status'); $ This-> dropColumn ( 'status%' 'created_by');  

Să începem migrarea:

./ yii migrați / up Instrument de migrare Yii (bazat pe Yii v2.0.1) Se va aplica o nouă migrare totală: m150128_003709_extend_status_table_for_created_by Aplicați migrarea de mai sus? (da | nu) [nu]: da *** aplicând m150128_003709_extend_status_table_for_created_by> adăugați o coloană create_by integer NOT NULL la tabel status status ... done (time: 0.009s)> adăugați cheie străină fk_status_created_by: % status (create_by) referințe % user (id) ... făcut (timpul: 0.007s) *** aplicat m150128_003709_extend_status_table_for_created_by (timpul: 0.020s).

Am reinceput generarea de coduri Gii cu noua tabelă de stare și am copiat și lipit noile elemente suplimentare. Cele mai multe au fost minore, dar veți observa că adaugă un nou ActiveQuery pentru relația:

 / ** * @return \ yii \ db \ ActiveQuery * / funcția publică getCreatedBy () return $ this-> hasOne (Utilizator :: className (), ['id' => 'created_by']);  

Deci, chiar înainte de salvarea unor elemente de stare noi, putem actualiza creat de cîmpul către utilizatorul conectat în prezent. Și putem avea încredere în controlul accesului pentru a ne asigura crea metoda este accesată numai de utilizatori autentificați:

funcția publică funcțiaCreate () $ model = new Status (); dacă ($ model-> încărcați (Yii :: $ app-> request-> post ())) $ model-> create_by = Yii :: $ app-> user-> getId (); $ model-> created_at = timp (); $ model-> updated_at = timp (); dacă ($ model-> save ()) retur $ this-> redirect (['view', 'id' => $ model-> id]);  returnați $ this-> render ('create', ['model' => model $,]); 

De asemenea, vom extinde widgetul de vizualizare pentru a include creat de camp:

  $ model, 'attributes' => ['id', 'message: ntext', 'created_by', 'permissions', 'created_at', 'updated_at',]

Putem folosi, de asemenea, creat de relație pentru afișarea adresei de e-mail:

  $ model, 'attributes' => ['id', 'createdBy.email', 'message: ntext', 'permissions', 'created_at', 'updated_at',] 

createdBy.email accesează Statut :: getCreatedBy metoda relației. Afișează adresa de e-mail a utilizatorului:

Cu toate acestea, pentru a susține această capacitate cu extensia Yii2-utilizator am implementat în partea a patra, a trebuit să facem două modificări. În primul rând, în nostru app \ config \ web.php , am adăugat o suprascriere a modelului app \ modele \ User.php:

... "user" => ['class' => 'dektrium \ user \ Module', 'enableUnconfirmedLogin' => true, 'confirmWithin' => 21600, => 'app \ models \ User',], 'admins' => ['admin']], 

De asemenea, am creat acest model în app \ modele:

Aceste două schimbări au oferit suport pentru relație.

Extinderea controalelor simple de acces

Dacă vrem să avem capacități suplimentare în ceea ce privește acțiunile controlerului? De exemplu, ce se întâmplă dacă vrem să restricționăm operațiile de ștergere către moderatori sau administratori? Controlul accesului simplu al lui Yii2 nu are un concept moderator sau administrator dacă nu îl creați cu RBAC.

Rețineți că extensia Yii2-user are un identificator de administrator pentru anumiți utilizatori, dar nu are prea multă flexibilitate pentru rolurile suplimentare.

Codul Ninja a scris un exemplu frumos de extindere a controalelor simple de acces pentru a sprijini moderatorii și administratorii (Autorizație simplă bazată pe roluri în Yii 2.0) fără a fi nevoie să recurgă la utilizarea RBAC. Exemplul lor funcționează cu șablonul de aplicație avansată Yii2. 

Aplicația noastră este diferită în sensul că folosim șablonul de bază al aplicației Yii și folosim extensia Yii2-utilizator. Prin urmare, am făcut câteva modificări în ghidul lor:

În primul rând, creăm un app \ componente director și și AccessRule.php fișier care extinde Yii încorporat AccessRule model:

roluri)) return true;  foreach ($ this-> roluri ca $ role) if ($ role == '?') if ($ user-> getIsGuest ()) return true;  elseif ($ rol == Utilizator :: ROLE_USER) if (! $ user-> getIsGuest ()) return true;  // Verificați dacă utilizatorul este conectat și rolurile se potrivesc elseif (! $ User-> getIsGuest () && $ role == $ user-> identitate-> role) return true;  return false; 

Apoi, adăugăm noi definiții de rol app \ modele \ utilizator model:

Yii2-utilizator nu implementează coloana de rol atunci când creează noi utilizatori. Deci, puteți specifica roluri pentru moderatori și administratori manual în MySQL sau puteți construi ulterior propria interfață de utilizator web pentru acordarea de roluri.

În furnizor \ dektrium \ yii2-user \ modele \ RegistrationForm.php, Am adăugat această linie pentru a defini rolul utilizatorilor pentru utilizatorii impliciți:

Notă: va trebui să faceți această modificare manuală dacă doriți, deoarece directorul furnizorului meu nu este verificat în arborele nostru GitHub - și da, probabil că există o modalitate mai elegantă de a face acest lucru în baza de date codebase după înregistrarea , de exemplu extindeți metoda createUser în app / models / User.php. Cea mai bună practică ar putea fi furculița depozitului furnizorilor și aducerea în arborele dvs. de cod propriu.

** * Înregistrează un nou cont de utilizator. * @return bool * / registrul funcțiilor publice () if ($ this-> validate ()) $ user = $ this-> module-> manager-> createUser (['scenario' => '=> $ this-> email,' username '=> $ this-> nume de utilizator,' password '=> $ this-> password,' role '=> 10, // User :: ROLE_USER;]); returnați $ user-> register ();  return false; 

În cele din urmă, în StatusController.php, adăugăm câteva biblioteci și aceste definiții de acces. În exemplul de mai jos, acțiunile de actualizare sunt restricționate la moderatori și acțiunile de ștergere sunt limitate la administratori.

 ['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post'],],] access = ), // vom suprascrie configurația regulilor implicite cu noua clasă AccessRule 'ruleConfig' => ['class' => AccessRule :: className (),], 'only' => ['index', ' 'update', 'delete'], 'rules' => [['actions' => ['index', 'create'], 'permit' => true, // Permite utilizatorilor, moderatorilor și administratorilor să creeze roluri '=> [Utilizator :: ROLE_USER, Utilizator :: ROLE_MODERATOR, Utilizator :: ROLE_ADMIN],], [' actions '=> [' update '],' allow '=> true, // Permite moderatorilor și administratorilor să actualizeze' roluri '=> [Utilizator :: ROLE_MODERATOR, Utilizator :: ROLE_ADMIN],] [' actions '=> [' delete '],' allow '=> true, // Permite administratorilor sa sterge rolurile = :: ROLE_ADMIN],],],];]; 

Acum, când vă deconectați și vizitați stare din bara de navigare, veți fi direcționați către ecranul de conectare:

Când te conectezi, vei fi trimis din nou la vizualizarea index:

Cu toate acestea, dacă fac clic Șterge, Voi primi această eroare de acces interzisă - pentru că sunt un utilizator slab, nu un administrator:

Dacă doriți să vă ridicați la administrator, puteți face acest lucru în baza de date, schimbând coloana rolului tabelului utilizator pentru user_id la 20 pentru moderator și 30 pentru administrator. Încercați din nou operațiile de actualizare și ștergere și vi se va permite, în funcție de rolul ales.

Controlul accesului este una dintre multele caracteristici care mă fac un avocat uriaș pentru utilizarea platformei Yii. Yii mă face un dezvoltator mult mai eficient, capabil să ofere soluții mult mai repede decât pot cu vanilla PHP.

Ce urmeaza?

Urmăriți tutorialele viitoare din programul meu de programare cu seria Yii2, deoarece continuam să scufundăm în diferite aspecte ale cadrului. Puteți, de asemenea, doriți să verificați starea mea Building Your Startup With PHP, care utilizează șablonul avansat al lui Yii2, pe măsură ce construiesc o aplicație din lumea reală.

Dacă doriți să știți când vine următorul tutorial Yii2, urmați-mă @reifman pe Twitter sau verificați pagina de instructor. Pagina mea de instructor va include toate articolele din această serie de îndată ce vor fi publicate. De asemenea, puteți să-mi trimiteți un e-mail pe site-ul meu Lookahead Consulting.

Link-uri conexe

  • Site-ul web Yii
  • Introducere în Cadrul Yii (Tuts +)
  • Yii2 Developer Exchange, site-ul meu de resurse Yii2
Cod