Slik programmerer du med Yii2 Brukertilgangskontroller

Hva du skal skape

Hvis du spør, "Hva er Yii?" sjekk ut min tidligere opplæring: Introduksjon til Yii Framework, som vurderer fordelene med Yii og inneholder en oversikt over hva som er nytt i Yii 2.0, utgitt i oktober 2014.

I denne programmeringen med Yii2-serien, er jeg veiledende lesere i bruk av den nylig oppgraderte Yii2 Framework for PHP. 

I del ett opprettet vi Yii2 lokalt, bygget et Hello World-program, opprettet en ekstern server og brukte Github til å distribuere koden vår. I del to lærte vi om Yiis implementering av sin Model View Controller-arkitektur og hvordan man bygger nettsider og skjemaer som samler og validerer data. 

I del tre brukte vi Yiis database og aktive rekordmuligheter for å automatisere kodegenerering for en grunnleggende webapplikasjon. I del fire lærte vi å integrere brukerregistrering. Og i del fem, undersøkte vi lokalisering med I18n for å forberede søknaden din til globale brukere. 

I denne opplæringen skal jeg vise deg hvordan du implementerer tilgangskontroller for å sikre at bare de riktige brukerne kan få tilgang til delene av programmet som vi ønsker dem.

For disse eksemplene fortsetter vi å forestille oss at vi bygger et rammeverk for å legge ut enkle statusoppdateringer, f.eks. vår egen mini-Twitter.

Bare en påminnelse, jeg deltar i kommentar tråder nedenfor. Jeg er spesielt interessert hvis du har forskjellige tilnærminger, flere ideer, eller ønsker å foreslå emner for fremtidige opplæringsprogrammer.

Hva er tilgangskontroll?

Tilgangskontroll integreres med rammens autentiseringsfunksjoner for å tillate eller begrense tilgang til bestemte funksjoner eller sider på nettstedet ditt. 

Koden vi har skrevet til nå, lar noen opprette innlegg selv om de ikke har logget på. For eksempel, i vårt eksempelprogram kan du besøke Status-siden og legge inn elementer uten å logge på. 

Vi kan bruke Yii2s enkle tilgangskontrollfunksjoner for å sikre at brukerne registrerer og logger på før du legger til og viser statusposter. 

Yii2 tilbyr også mer avansert (og kompleks) Role Based Access Control (RBAC) som vi ikke vil implementere på dette tidspunktet. Med RBAC definerer du et sofistikert hierarki av tillatelser for hver mulig aktivitet i søknaden din.

Yii2 er innebygd i Access Control støtter bare to roller som standard: gjest (ikke innlogget), representert av '?' Og autentisert, representert av '@'. Med enkle tilgangskontroller kan vi bare begrense tilgangen til bestemte sider eller kontrollerhandlinger basert på innloggingsstaten. Hvis brukerne ikke er logget inn når de besøker stedssidene, vil Yii omdirigere dem til påloggingssiden.

I denne opplæringen vil jeg introdusere deg til å bruke Yii2s enkle tilgangskontroller for vårt eksempelprogram. Da utvider vi enkel tilgang med flere roller som moderator og administrator.

Implementere enkle tilgangskontroller

For øyeblikket gir vår søknad tilgang til StatusController selv uten å logge inn. La oss fikse det.

Rammen gjør det ganske enkelt å implementere disse kontrollene. Vi legger bare til adferd til StatusController.php som definerer tilgangsregler for hver handling, f.eks. indeks, opprett, vis, osv. 

Her vil vi se gjennom tilgangsadferd, men hvis du er interessert, tillater YiS vertsfiltre deg å begrense forespørsel fra http-forespørsler basert på kontrolleren din.

offentlige funksjonsegenskaper () return ['verbs' => ['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post'],], => ['class' => \ yii \ filters \ AccessControl :: className (), 'only' => ['index', 'opprett', 'oppdater', 'visning'], 'regler' => [/ / tillat godkjente brukere ['allow' => true, 'rolls = = [' @ '],], // alt annet nektes],],]; 

Når du har lagt til, hvis du klikker på Status menyen, blir du omdirigert til påloggingssiden:

Yii håndterer viderekoblingen tilbake til Statusindeks siden når loggingen er fullført.

Legge til modell eierskap

Nå, når brukere får tilgang til Status-sidene, kan vi finne den nåværende brukeren med denne koden:

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

Og vi kan knytte statusposter med sin skaperen i modellen.

For å gjøre dette må vi utvide statustabellen med en ny tabelloverføring:

./ yii migrere / opprett extend_status_table_for_created_by Yii Migreringsverktøy (basert på Yii v2.0.1) Opprett ny migrasjon '/Users/Jeff/Sites/hello/migrations/m150128_003709_extend_status_table_for_created_by.php'? (ja | nei) [nei]: ja Ny migrasjon ble opprettet.

Her er overføringskoden som legger til en kolonne for laget av. Vi legger også til en utenlandsk nøkkel for å opprette en relasjon mellom Status> CREATED_BY felt og Bruker-> id bord.

db-> drivernavn === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> addColumn ('% status', 'created_by', Schema :: TYPE_INTEGER. 'IKKE NULL'); $ this-> addForeignKey ('fk_status_created_by', '% status', 'created_by', '% user', 'id', 'CASCADE', 'CASCADE');  offentlig funksjon ned () $ this-> dropForeignKey ('fk_status_created_by', '% status'); $ Dette-> dropColumn ( '% status', 'CREATED_BY');  

La oss kjøre overføringen:

./ yii migrere / opp Yii Migreringsverktøy (basert på Yii v2.0.1) Totalt 1 ny migrasjon som skal brukes: m150128_003709_extend_status_table_for_created_by Bruk overføringen ovenfor? (ja | nei) nei: ja *** gjelder m150128_003709_extend_status_table_for_created_by> legg til kolonne created_by heltall IKKE NULL til tabell % status ... ferdig (tid: 0.009s)> legg til utenlandsk nøkkel fk_status_created_by: % status (created_by) referanser % user (id) ... ferdig (tid: 0.007s) *** brukt m150128_003709_extend_status_table_for_created_by (tid: 0.020s) Migrert opp med hell.

Jeg re-sprang Gii-kodegenerasjonen med den nye statustabellen og kopierte og limte inn de nye ekstraelementene. De fleste var små, men du vil legge merke til det legger til en ny ActiveQuery for forholdet:

 / ** * @return \ yii \ db \ ActiveQuery * / offentlig funksjon getCreatedBy () return $ this-> hasOne (Bruker :: className (), ['id' => 'created_by']);  

Så, før nye statuselementer blir lagret, kan vi oppdatere laget av feltet til den innloggede brukeren. Og vi kan stole på tilgangskontroller for å sikre skape Metoden er bare tilgjengelig av godkjente brukere:

offentlig funksjon actionCreate () $ model = new Status (); hvis ($ modell-> last (Yii :: $ app-> forespørsel-> post ())) $ model-> created_by = Yii :: $ app-> bruker-> getId (); $ model-> created_at = time (); $ model-> updated_at = time (); hvis ($ model-> save ()) return $ this-> omdirigere (['view', 'id' => $ model-> id]);  returnere $ this-> render ('create', ['model' => $ modell,]); 

Vi vil også utvide visningsgrensen for å inkludere laget av felt:

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

Vi kan også bruke laget av forhold til å vise e-postadressen:

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

De createdBy.email tilgang til Status :: getCreatedBy relasjonsmetode. Dette viser brukerens e-postadresse:

For å kunne støtte denne muligheten med Yii2-brukerutvidelsen vi implementerte i del fire måtte vi imidlertid gjøre to modifikasjoner. Først i vår app \ config \ web.php konfigurasjonsarray, har vi lagt til en modelloverstyring til app \ modeller \ User.php:

... 'user' => '' dektrium \ user \ Modul ',' enableUnconfirmedLogin '=> sann,' confirmWithin '=> 21600,' cost '=> 12,' modelMap '=> [' Bruker ' => 'app \ models \ User',], 'admins' => ['admin']], 

Vi har også opprettet denne modellen i app \ modeller:

Disse to endringene ga støtte for forholdet.

Utvide enkle tilgangskontroller

Hva om vi ønsket å ha ekstra kapasitet rundt kontrollerhandlinger? For eksempel, hva om vi vil begrense slettingsoperasjoner til moderatorer eller administratorer? Yii2s enkle tilgangskontroll har ikke et moderator- eller administratorkonsept med mindre du oppretter en med RBAC.

Vær oppmerksom på at Yii2-brukerutvidelsen har en adminidentifikator for bestemte brukere, men det mangler også fleksibiliteten for flere roller.

Koden Ninja skrev et godt eksempel på å utvide enkle tilgangskontroller for å støtte moderatorer og administratorer (enklere rollebasert autorisasjon i Yii 2.0) uten å måtte ty til bruk av RBAC. Deres eksempel fungerer med Yii2 avansert applikasjonsmal. 

Vår søknad er annerledes ved at vi bruker Yii grunnleggende applikasjonsmal og Vi bruker Yii2-brukerutvidelsen. Derfor har jeg gjort noen endringer i sin guide:

Først oppretter vi en app \ komponenter katalog og og en AccessRule.php fil som utvider Yii er innebygd AccessRule modell:

roller)) return true;  foreach ($ this-> roller som $ rolle) if ($ role == '?') if ($ user-> getIsGuest ()) return true;  elseif ($ role == Bruker :: ROLE_USER) if (! $ user-> getIsGuest ()) return true;  // Sjekk om brukeren er logget inn, og rollene samsvarer med elseif (! $ User-> getIsGuest () && $ role == $ bruker-> identitet-> rolle) return true;  returnere false; 

Deretter legger vi til rolledefinisjoner til vår app \ modeller \ Bruker modell:

Yii2-user implementerer ikke rollens kolonne når du oppretter nye brukere. Så du kan enten spesifisere roller for moderatorer og administratorer manuelt i MySQL eller senere bygge ditt eget webgrensesnitt for å gi roller.

I leverandør \ dektrium \ yii2-user \ modeller \ RegistrationForm.php, Jeg har lagt til denne linjen for å definere brukerrollen for standardbrukere:

Merk: Du må gjøre denne endringen manuelt hvis du vil ha det fordi leverandørkatalogen ikke blir sjekket inn i vårt GitHub-tre - og ja det er nok en mer elegant måte å gjøre dette på i kjernekodebase etter registrering , f.eks utvide createUser-metoden i app / models / User.php. Best praksis kan være å gaffel leverandørregisteret og ta det inn i ditt eget kode tre.

** * Registrerer en ny brukerkonto. * @return bool * / offentlig funksjon register () hvis ($ dette-> validere ()) $ user = $ this-> modul-> manager-> createUser (['scenario' => 'register' '=> $ this-> email,' brukernavn '=> $ dette-> brukernavn,' passord '=> $ dette-> passord,' rolle '=> 10, // Bruker :: ROLE_USER;]); returnere $ user-> register ();  returner falsk; 

Til slutt, i StatusController.php, Vi legger til noen biblioteker og disse tilgangsdefinisjonene. I eksemplet nedenfor er oppdateringshandlinger begrenset til moderatorer, og slettehandlinger er begrenset til administratorer.

 ['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post'],],], 'access' => ['class' => AccessControl :: className ), // Vi vil overstyre standardregelen config med den nye AccessRule-klassen ruleConfig '=> [' class '=> AccessRule :: className (),],' only '=> [' index ',' create ' 'Oppdater', 'Slett'], 'Rules' => [['actions' => ['index', 'create'], 'allow' => true, // Tillat brukere, moderatorer og admins å opprette 'roller '=> [Bruker :: ROLE_USER, Bruker :: ROLE_MODERATOR, Bruker :: ROLE_ADMIN],], [' actions '=> [' update '],' allow '=> true, // Tillat moderatorer og administratorer å oppdatere' Rolle '=> [Bruker :: ROLE_MODERATOR, Bruker :: ROLE_ADMIN],], [' actions '=> [' delete '],' allow '=> true, // Tillat admins å slette' roles '=> [Bruker :: ROLE_ADMIN],],],],]; 

Nå, når du logger ut og besøker Status siden fra navigasjonslinjen, blir du tatt til påloggingsskjermen:

Når du logger på, blir du sendt til indeksvisningen igjen:

Men hvis jeg klikker Slett, Jeg vil få denne tilgangen forbudt feil - fordi jeg er en dårlig bruker, ikke en administrator:

Hvis du vil heve deg selv til administratoren, kan du gjøre det i databasen, endre brukertabellens rollekolonne for brukeren din til 20 for moderator og 30 for admin. Prøv oppdateringen og slett operasjonen igjen, og du vil bli tillatt avhengig av hvilken rolle du har valgt.

Tilgangskontroller er en av de mange funksjonene som gjør meg til en stor talsmann for å bruke Yii Framework. Yii gjør meg en mye mer effektiv utvikler, i stand til å levere løsninger mye raskere enn jeg kan med vanilje PHP.

Hva blir det neste?

Se etter kommende opplæringsprogrammer i min programmering med Yii2-serien når jeg fortsetter å dykke inn i ulike aspekter av rammen. Du vil kanskje også sjekke ut Bygg opp din oppstart med PHP-serien, som bruker Yii2s avanserte mal, da jeg bygger en ekte verdensapplikasjon.

Hvis du vil vite når neste Yii2 opplæring kommer, følg meg @ reifman på Twitter eller sjekk min instruktørside. Min instruktørside vil inkludere alle artiklene fra denne serien så snart de er publisert. Du kan også sende meg en e-post på Lookahead Consulting.

Relaterte linker

  • Yii Framework Website
  • Introduksjon til Yii Framework (Tuts +)
  • Yii2 Developer Exchange, min Yii2 ressurs side