Als je vraagt: "Wat is Yii?" bekijk mijn eerdere tutorial: Introductie tot het Yii Framework, die de voordelen van Yii bekijkt en een overzicht bevat van wat er nieuw is in Yii 2.0, uitgebracht in oktober 2014.
In deze Programming With Yii2-serie leid ik lezers in gebruik van het onlangs bijgewerkte Yii2 Framework voor PHP.
In deel een hebben we Yii2 lokaal opgezet, een Hello World-applicatie gebouwd, een externe server opgezet en Github gebruikt om onze code te implementeren. In deel twee hebben we geleerd over Yii's implementatie van de Model View Controller-architectuur en hoe webpagina's en formulieren te bouwen die gegevens verzamelen en valideren.
In deel drie hebben we Yii's database en actieve recordmogelijkheden gebruikt om het genereren van de code voor een eenvoudige webtoepassing te automatiseren. In deel vier leerden we hoe we gebruikersregistratie integreerden. En in deel vijf hebben we de lokalisatie met I18n onderzocht om je toepassing voor wereldwijde gebruikers voor te bereiden.
In deze zelfstudie laat ik u zien hoe u toegangscontroles implementeert om ervoor te zorgen dat alleen de juiste gebruikers toegang hebben tot de delen van onze applicatie die we willen dat ze.
Voor deze voorbeelden blijven we ons voorstellen dat we een raamwerk bouwen voor het plaatsen van eenvoudige statusupdates, bijvoorbeeld onze eigen mini-Twitter.
Ter herinnering, ik neem wel deel aan de commentaarthreads hieronder. Ik ben vooral geïnteresseerd in verschillende benaderingen, aanvullende ideeën of onderwerpen voor toekomstige zelfstudies.
Toegangscontrole integreert met de authenticatiefuncties van het framework om de toegang tot specifieke functies of pagina's van uw website toe te staan of te beperken.
De code die we tot nu toe hebben geschreven, stelt iedereen in staat om berichten te maken, zelfs als ze zich niet hebben aangemeld. In onze voorbeeldtoepassing kun je de statuspagina bezoeken en items posten zonder in te loggen.
We kunnen de eenvoudige toegangscontrolefuncties van Yii2 gebruiken om ervoor te zorgen dat gebruikers zich registreren en inloggen voordat ze statusberichten toevoegen en bekijken.
Yii2 biedt ook meer geavanceerde (en complexe) Role Based Access Control (RBAC) die we op dit moment niet zullen implementeren. Met RBAC definieert u een geavanceerde hiërarchie van machtigingen voor elke mogelijke activiteit in uw toepassing.
Yii2's ingebouwde Access Control ondersteunt standaard slechts twee rollen: gast (niet ingelogd), weergegeven door '?', En geverifieerd, weergegeven door '@'. Met eenvoudige toegangscontroles kunnen we de toegang tot specifieke pagina's of controlleracties beperken op basis van de aanmeldingsstatus. Als gebruikers niet zijn aangemeld wanneer ze de plaatspagina's bezoeken, leidt Yii ze om naar de inlogpagina.
In deze zelfstudie zal ik u laten kennismaken met het gebruik van Yii2's eenvoudige toegangscontroles voor onze voorbeeldtoepassing. Daarna breiden we eenvoudige toegang uit met extra rollen, zoals moderator en beheerder.
Op dit moment geeft onze applicatie toegang tot de StatusController, zelfs zonder in te loggen. Laten we dat oplossen.
Het kader maakt het vrij eenvoudig om deze besturingselementen te implementeren. We voegen gewoon gedrag toe aan StatusController.php die de toegangsregels definiëren voor elke actie, bijvoorbeeld index, maken, bekijken, enz.
Hier zullen we het toegangsgedrag beoordelen, maar als je geïnteresseerd bent, kun je met de werkwoordfilters van Yii HTTP-verzoekbewerkingen beperken op basis van je controlleractie.
public function behaviors () return ['werkwoorden' => ['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post'],],], 'access' => ['class' => \ yii \ filters \ AccessControl :: className (), 'only' => ['index', 'create', 'update', 'view'], 'rules' => [/ / gemachtigde gebruikers toestaan ['allow' => true, 'roles' => ['@'],], // al het andere wordt geweigerd],],];
Als u eenmaal hebt geklikt, klikt u op staat menu, wordt u doorgestuurd naar de inlogpagina:
Yii verwerkt de omleiding ook weer naar de statusindexpagina zodra de aanmelding is voltooid.
Wanneer gebruikers nu de statuspagina's openen, kunnen we de huidige gebruiker met deze code vinden:
Yii :: $ app-> gebruiksvriendelijkheid> getId ();
En we kunnen statusberichten koppelen aan hun maker in het model.
Om dit te doen, moeten we de Status-tabel uitbreiden met een nieuwe tabelmigratie:
./ yii migrate / create extend_status_table_for_created_by Yii Migration Tool (gebaseerd op Yii v2.0.1) Maak nieuwe migratie '/Users/Jeff/Sites/hello/migrations/m150128_003709_extend_status_table_for_created_by.php'? (ja | nee) [nee]: ja Nieuwe migratie is succesvol gemaakt.
Hier is de migratiecode waaraan een kolom wordt toegevoegd gemaakt door
. We voegen ook een externe sleutel toe om een relatie te creëren tussen de Status-> created_by
veld en de User-> id
tafel.
db-> driverName === 'mysql') $ tableOptions = 'KARAKTER SET 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 ( '% de status', 'created_by');
Laten we de migratie uitvoeren:
./ yii migreren / omhoog Yii Migration Tool (gebaseerd op Yii v2.0.1) Totaal 1 nieuwe migratie die moet worden toegepast: m150128_003709_extend_status_table_for_created_by De bovenstaande migratie toepassen? (yes | no) [nee]: yes *** apply m150128_003709_extend_status_table_for_created_by> voeg column created_by integer NOT NULL toe aan table % status ... done (time: 0.009s)> add foreign key fk_status_created_by: % status (created_by) references % user (id) ... done (time: 0.007s) *** applied m150128_003709_extend_status_table_for_created_by (time: 0.020s) Migratie succesvol uitgevoerd.
Ik heb de Gii-codegeneratie opnieuw uitgevoerd met de nieuwe Status-tabel en de nieuwe aanvullende elementen gekopieerd en geplakt. De meeste waren klein, maar u zult merken dat het een nieuw ActiveQuery toevoegt voor de relatie:
/ ** * @return \ yii \ db \ ActiveQuery * / public function getCreatedBy () return $ this-> hasOne (User :: className (), ['id' => 'created_by']);
Dus net voordat nieuwe statusitems worden opgeslagen, kunnen we de gemaakt door
naar de momenteel ingelogde gebruiker. En we kunnen op toegangscontroles vertrouwen om de creëren
methode is alleen toegankelijk voor geverifieerde gebruikers:
public function actionCreate () $ model = nieuwe 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]); return $ this-> render ('create', ['model' => $ model,]);
We breiden ook de weergavewidget uit met de gemaakt door
veld:
= DetailView::widget([ 'model' => $ model, 'attributen' => ['id', 'message: ntext', 'created_by', 'permissions', 'created_at', 'updated_at',],])?>
We kunnen ook de gemaakt door
relatie om het e-mailadres weer te geven:
= DetailView::widget([ 'model' => $ model, 'attributen' => ['id', 'createdBy.email', 'message: ntext', 'permissions', 'created_at', 'updated_at',],])?>
De createdBy.email
toegang tot de Status :: getCreatedBy
relatie methode. Hier wordt het e-mailadres van de gebruiker weergegeven:
Om deze mogelijkheid met de Yii2-gebruikersuitbreiding die we in deel vier implementeerden te ondersteunen, moesten we echter twee wijzigingen aanbrengen. Ten eerste, in onze app \ config \ web.php
configuratie array, hebben we een modeloverbrugging toegevoegd aan app \ modellen \ User.php
:
... 'user' => ['class' => 'dektrium \ user \ Module', 'enableUnconfirmedLogin' => true, 'confirmWithin' => 21600, 'cost' => 12, 'modelMap' => ['Gebruiker' => 'app \ modellen \ Gebruiker',], 'admins' => ['admin']],
We hebben dit model ook gemaakt in app \ modellen
:
namespace app\models; use dektrium\user\models\User as BaseUser; class User extends BaseUser public function register() // do your magic ?>
Deze twee veranderingen hebben de relatie ondersteund.
Wat als we extra capaciteit wilden hebben rond controlleracties? Wat als we bijvoorbeeld verwijderbewerkingen willen beperken tot moderators of beheerders? Yii2's eenvoudige toegangscontrole heeft geen moderator- of beheerdersconcept tenzij u er een maakt met RBAC.
Merk op dat de Yii2-gebruikersextensie een beheerders-ID heeft voor specifieke gebruikers, maar ook de flexibiliteit voor extra rollen ontbreekt.
De Code Ninja schreef een mooi voorbeeld van uitbreiding van eenvoudige toegangscontroles om moderators en administrators te ondersteunen (Simpler Role Based Authorization in Yii 2.0) zonder toevlucht te hoeven nemen tot het gebruik van RBAC. Hun voorbeeld werkt met de geavanceerde toepassingssjabloon van Yii2.
Onze applicatie is anders omdat we de basis-applicatiesjabloon van Yii gebruiken en we gebruiken de Yii2-gebruikersextensie. Daarom heb ik een aantal wijzigingen aangebracht in hun gids:
Eerst maken we een app \ componenten
map en en een AccessRule.php
bestand dat de ingebouwde Yii uitbreidt AccessRule
model:
rollen)) return true; foreach ($ this-> roles as $ role) if ($ role == '?') if ($ user-> getIsGuest ()) return true; elseif ($ role == User :: ROLE_USER) if (! $ user-> getIsGuest ()) return true; // Controleer of de gebruiker is aangemeld en of de rollen overeenkomen elseif (! $ User-> getIsGuest () && $ role == $ user-> identity-> role) return true; return false;
Vervolgens voegen we roldefinities toe aan onze app \ modellen \ User
model:
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-user
implementeert de rolkolom niet bij het maken van nieuwe gebruikers. U kunt dus handmatig moderators en beheerders opgeven in MySQL of later uw eigen webgebruikersinterface bouwen om rollen toe te wijzen.
In vendor \ dektrium \ yii2-user \ modellen \ RegistrationForm.php
, Ik heb deze regel toegevoegd om de gebruikersrol voor standaardgebruikers te definiëren:
Opmerking: u moet deze wijziging handmatig uitvoeren als u dat wilt, omdat mijn leveranciersdirectory niet wordt ingecheckt in onze GitHub-structuur - en ja, er is waarschijnlijk een elegantere manier om dit in de kerncode te doen nadat registratie heeft plaatsgevonden , bijv breid de createUser-methode uit in app / models / User.php. De beste manier is om de leverancierrepository te doorzoeken en deze in uw eigen codestructuur te plaatsen.
** * Registreert een nieuw gebruikersaccount. * @return bool * / public function register () if ($ this-> validate ()) $ user = $ this-> module-> manager-> createUser (['scenario' => 'register', 'email '=> $ dit-> email,' gebruikersnaam '=> $ dit-> gebruikersnaam,' wachtwoord '=> $ dit-> wachtwoord,' rol '=> 10, // Gebruiker :: ROLE_USER;]); return $ user-> register (); return false;
Eindelijk, in StatusController.php
, we voegen een aantal bibliotheken en deze toegangsdefinities toe. In het onderstaande voorbeeld zijn updateacties beperkt tot moderators en zijn verwijderingsacties beperkt tot beheerders.
['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post'],],], 'access' => ['class' => AccessControl :: className ( ), // We zullen de standaard regelconfiguratie overschrijven met de nieuwe AccessRule-klasse 'ruleConfig' => ['class' => AccessRule :: className (),], 'only' => ['index', 'create', 'update', 'delete'], 'rules' => [['actions' => ['index', 'create'], 'allow' => true, // Gebruikers, moderators en beheerders toestaan 'rollen' te maken '=> [Gebruiker :: ROLE_USER, Gebruiker :: ROLE_MODERATOR, Gebruiker :: ROLE_ADMIN],], [' actions '=> [' update '],' allow '=> true, // Moderators en beheerders toestaan te updaten' roles '=> [User :: ROLE_MODERATOR, User :: ROLE_ADMIN],], [' actions '=> [' delete '],' allow '=> true, // Beheerders toestaan' rollen 'te verwijderen => [Gebruiker :: ROLE_ADMIN],],],],];
Nu, wanneer u uitlogt en de staat pagina van de navigatiebalk, gaat u naar het inlogscherm:
Wanneer u zich aanmeldt, wordt u opnieuw naar de indexweergave gestuurd:
Als ik echter klik Verwijder, Ik krijg deze foutmelding met toegang tot de toegang - omdat ik een eenvoudige gebruiker en geen beheerder ben:
Als u uzelf wilt verheffen tot beheerder, kunt u dit doen in de database, de rolkolom van de gebruikerstabel wijzigen voor uw user_id in 20 voor moderator en 30 voor admin. Probeer de update opnieuw en verwijder bewerkingen en je bent toegestaan, afhankelijk van de rol die je hebt gekozen.
Toegangscontrole is een van de vele functies die me een grote voorstander maken van het gebruik van het Yii Framework. Yii maakt me een veel efficiëntere ontwikkelaar, in staat om veel sneller oplossingen te leveren dan ik kan met vanilla PHP.
Kijk uit naar komende tutorials in mijn Programming With Yii2-serie terwijl ik verder duik in verschillende aspecten van het framework. Je kunt ook mijn Building Your Startup With PHP-serie bekijken, die de geavanceerde sjabloon van Yii2 gebruikt terwijl ik een toepassing in de echte wereld samenstel.
Als je wilt weten wanneer de volgende Yii2-handleiding aankomt, volg me dan @reifman op Twitter of bekijk mijn instructeurspagina. Op mijn instructeurspagina staan alle artikelen uit deze serie zodra ze zijn gepubliceerd. Je kunt me ook e-mailen op mijn Lookahead Consulting-website.