Wenn Sie fragen: "Was ist Yii?" Schauen Sie sich mein früheres Tutorial an: Einführung in das Yii-Framework, Hier werden die Vorteile von Yii beschrieben und ein Überblick über die Neuerungen in Yii 2.0 (Oktober 2014) gegeben.
In dieser Programmierserie mit Yii2 leite ich die Leser beim Einsatz des neu aktualisierten Yii2-Frameworks für PHP.
Im ersten Teil haben wir Yii2 lokal eingerichtet, eine Hello World-Anwendung erstellt, einen Remote-Server eingerichtet und Github zur Bereitstellung unseres Codes verwendet. In Teil zwei haben wir erfahren, wie Yii seine Model View Controller-Architektur implementiert und wie Webseiten und Formulare erstellt werden, die Daten sammeln und validieren.
In Teil drei haben wir die Datenbank- und Active Record-Funktionen von Yii verwendet, um die Codegenerierung für eine grundlegende Webanwendung zu automatisieren. In Teil 4 haben wir gelernt, die Benutzerregistrierung zu integrieren. In Teil fünf haben wir mit I18n die Lokalisierung untersucht, um Ihre Anwendung für globale Benutzer vorzubereiten.
In diesem Tutorial werde ich Ihnen zeigen, wie Sie Zugriffskontrollen implementieren, um sicherzustellen, dass nur die richtigen Benutzer auf die Teile unserer Anwendung zugreifen können, die wir wünschen.
Für diese Beispiele stellen wir uns weiterhin vor, dass wir ein Framework für die Veröffentlichung einfacher Statusaktualisierungen erstellen, z. unser eigenes Mini-Twitter.
Nur zur Erinnerung, ich beteilige mich an den Kommentarthreads unten. Ich bin besonders interessiert, wenn Sie unterschiedliche Ansätze, zusätzliche Ideen haben oder Themen für zukünftige Tutorials vorschlagen möchten.
Die Zugriffskontrolle ist in die Authentifizierungsfunktionen des Frameworks integriert, um den Zugriff auf bestimmte Funktionen oder Seiten Ihrer Website zu ermöglichen oder einzuschränken.
Der Code, den wir bisher geschrieben haben, ermöglicht es jedem, Beiträge zu erstellen, auch wenn sie sich nicht angemeldet haben. In unserer Beispielanwendung können Sie beispielsweise die Statusseite besuchen und Elemente posten, ohne sich anzumelden.
Wir können die einfachen Zugriffskontrollfunktionen von Yii2 verwenden, um sicherzustellen, dass sich Benutzer registrieren und anmelden, bevor Statusbeiträge hinzugefügt und angezeigt werden.
Yii2 bietet auch eine erweiterte (und komplexe) rollenbasierte Zugriffskontrolle (Role Based Access Control, RBAC), die wir derzeit nicht implementieren werden. Mit RBAC definieren Sie eine differenzierte Hierarchie von Berechtigungen für jede mögliche Aktivität in Ihrer Anwendung.
Die integrierte Zugriffskontrolle von Yii2 unterstützt standardmäßig nur zwei Rollen: guest (nicht angemeldet), dargestellt durch "?", Und authentifiziert, dargestellt durch "@". Mit einfachen Zugriffskontrollen können wir den Zugriff auf bestimmte Seiten oder Controller-Aktionen basierend auf dem Anmeldezustand beschränken. Wenn Benutzer beim Besuch der Ortsseiten nicht angemeldet sind, werden sie von Yii auf die Anmeldeseite umgeleitet.
In diesem Lernprogramm werde ich Sie mit der einfachen Zugriffskontrolle von Yii2 für unsere Beispielanwendung vertraut machen. Dann erweitern wir den einfachen Zugriff um zusätzliche Rollen wie Moderator und Administrator.
Derzeit erlaubt unsere Anwendung den Zugriff auf den StatusController auch ohne Anmeldung. Lassen Sie uns das beheben.
Das Framework macht es recht einfach, diese Steuerelemente zu implementieren. Wir fügen der StatusController.php einfach Verhalten hinzu, die die Zugriffsregeln für jede Aktion definieren, z. Indexieren, Erstellen, Anzeigen usw.
Hier überprüfen wir das Zugriffsverhalten. Wenn Sie jedoch interessiert sind, können Sie mit den Verb-Filtern von Yi HTTP-Anforderungsoperationen basierend auf Ihrer Controller-Aktion einschränken.
public function behaviors () return ['verbs' => ['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post'] "],], 'access' => ['class' => \ yii \ filters \ AccessControl :: className (), 'only' => ['index', 'create', 'update', 'view'], 'rules' => [/ / Erlaube authentifizierte Benutzer ['allow' => true, 'rolls' => ['@'],], // alles andere wird abgelehnt],],];
Einmal hinzugefügt, wenn Sie auf klicken Status Menü werden Sie zur Anmeldeseite weitergeleitet:
Yii übernimmt auch die Rückleitung zur Status-Indexseite, sobald die Anmeldung abgeschlossen ist.
Wenn Benutzer jetzt auf die Statusseiten zugreifen, können wir den aktuellen Benutzer mit diesem Code finden:
Yii :: $ app-> user-> getId ();
Und wir können Statusbeiträge mit ihrem Ersteller im Modell verknüpfen.
Dazu müssen wir die Statustabelle um eine neue Tabellenmigration erweitern:
./ yii migrieren / erstellen extend_status_table_for_created_by Yii Migration Tool (basierend auf Yii v2.0.1) Neue Migration erstellen '/Users/Jeff/Sites/hello/migrations/m150128_003709_extend_status_table_for_created_by.php'? (ja | nein) [nein]: ja Die neue Migration wurde erfolgreich erstellt.
Hier ist der Migrationscode, der eine Spalte für hinzufügt erstellt von
. Wir fügen auch einen Fremdschlüssel hinzu, um eine Beziehung zwischen dem Status-> created_by
Feld und die Benutzer-> ID
Tabelle.
db-> driverName === 'mysql') $ tableOptions = 'CHARACTER 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 ('% status', 'created_by');
Lassen Sie uns die Migration ausführen:
./ yii migrieren / up Yii Migration Tool (basierend auf Yii v2.0.1) Insgesamt 1 neu anzuwendende Migration: m150128_003709_extend_status_table_for_created_by Anwenden der obigen Migration? (Ja | Nein) [Nein]: Ja *** Anwenden von m150128_003709_extend_status_table_for_created_by> füge Spalte create_by integer NOT NULL zur Tabelle % status hinzu ... done (Zeit: 0,009 s)> Fremdschlüssel hinzufügen fk_status_created_by: % status (created_by) referenziert % user (id)… done (Zeit: 0,007s) *** angewendet m150128_003709_extend_status_table_for_created_by (Zeit: 0,020s) Erfolgreich migriert.
Ich habe die Gii-Code-Generierung mit der neuen Statustabelle erneut ausgeführt und die neuen zusätzlichen Elemente kopiert und eingefügt. Die meisten waren geringfügig, aber Sie werden feststellen, dass für die Beziehung eine neue ActiveQuery hinzugefügt wird:
/ ** * @return \ yii \ db \ ActiveQuery * / public function getCreatedBy () return $ this-> hasOne (Benutzer :: Klassenname (), ['id' => 'created_by']);
Kurz bevor neue Statuselemente gespeichert werden, können wir das aktualisieren erstellt von
Feld zum aktuell angemeldeten Benutzer. Und wir können den Zugriffskontrollen vertrauen, um sicherzustellen, dass erstellen
Auf diese Methode wird nur von authentifizierten Benutzern zugegriffen:
öffentliche Funktion 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]); return $ this-> render ('create', ['model' => $ model,]);
Wir erweitern auch das Ansichts-Widget um das erstellt von
Feld:
= DetailView::widget([ 'model' => $ model, 'attributes' => ['id', 'message: ntext', 'created_by', 'Berechtigungen', 'created_at', 'updated_at',],])?>
Wir können auch die verwenden erstellt von
Beziehung zur Anzeige der E-Mail-Adresse:
= DetailView::widget([ 'model' => $ model, 'attributes' => ['id', 'createdBy.email', 'message: ntext', 'permissions', 'created_at', 'updated_at',],])?>
Das createdBy.email
greift auf die Status :: getCreatedBy
Beziehungsmethode. Hier wird die E-Mail-Adresse des Benutzers angezeigt:
Um diese Funktion mit der in Teil 4 implementierten Yii2-Benutzererweiterung zu unterstützen, mussten wir jedoch zwei Modifikationen vornehmen. Zuerst in unserem app \ config \ web.php
Konfigurations-Array haben wir eine Modell-Überschreibung hinzugefügt app \ models \ User.php
:
… 'User' => ['class' => 'dektrium \ user \ Module', 'enableUnconfirmedLogin' => true, 'confirmWithin' => 21600, 'cost' => 12, 'modelMap' => ['User' => 'app \ models \ User',], 'admins' => ['admin']],
Dieses Modell haben wir auch in erstellt app \ models
:
namespace app\models; use dektrium\user\models\User as BaseUser; class User extends BaseUser public function register() // do your magic ?>
Diese beiden Änderungen unterstützten die Beziehung.
Was wäre, wenn wir zusätzliche Funktionen für Controller-Aktionen haben wollten? Was ist beispielsweise, wenn wir Löschvorgänge auf Moderatoren oder Administratoren beschränken möchten? Die einfache Zugriffskontrolle von Yii2 verfügt nicht über ein Moderator- oder Administratorkonzept, es sei denn, Sie erstellen ein solches mit RBAC.
Beachten Sie, dass die Erweiterung von Yii2-Benutzern eine Administrator-ID für bestimmte Benutzer enthält, aber es fehlt auch die Flexibilität für zusätzliche Rollen.
The Code Ninja hat ein schönes Beispiel für die Erweiterung der einfachen Zugriffskontrolle auf die Unterstützung von Moderatoren und Administratoren (Simpler Role Based Authorization in Yii 2.0) beschrieben, ohne auf RBAC zurückgreifen zu müssen. Ihr Beispiel funktioniert mit der erweiterten Anwendungsvorlage Yii2.
Unsere Anwendung unterscheidet sich dahingehend, dass wir die grundlegende Anwendungsvorlage von Yii verwenden und Wir verwenden die Yii2-User-Erweiterung. Daher habe ich einige Änderungen an ihrem Leitfaden vorgenommen:
Zuerst erstellen wir eine App \ Komponenten
Verzeichnis und und ein AccessRule.php
Datei, die Yiis eingebaute erweitert Zugriffsregel
Modell:
Rollen)) return true; foreach ($ this-> rollen als $ role) if ($ role == '?') if ($ user-> getIsGuest ()) return true; elseif ($ role == User :: ROLE_USER) if (! $ user-> getIsGuest ()) return true; // Prüfen Sie, ob der Benutzer angemeldet ist und die Rollen übereinstimmen elseif (! $ User-> getIsGuest () && $ role == $ user-> identity-> role) return true; falsch zurückgeben;
Dann fügen wir unserer Definition Rollendefinitionen hinzu app \ models \ user
Modell:
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-Benutzer
implementiert die Rollenspalte beim Erstellen neuer Benutzer nicht. So können Sie entweder Rollen für Moderatoren und Administratoren manuell in MySQL angeben oder später eine eigene Webbenutzeroberfläche für die Rollenvergabe erstellen.
Im vendor \ dektrium \ yii2-user \ models \ RegistrationForm.php
, Ich habe diese Zeile hinzugefügt, um die Benutzerrolle für Standardbenutzer zu definieren:
Hinweis: Sie müssen diese Änderung manuell vornehmen, wenn Sie dies wünschen, da mein Herstellerverzeichnis nicht in unseren GitHub-Baum eingecheckt wird. Ja, in der Core-Codebase gibt es wahrscheinlich eine elegantere Methode, nachdem die Registrierung erfolgt , z.B Erweitern Sie die createUser-Methode in app / models / User.php. Es empfiehlt sich, das Vendor-Repository in einen eigenen Codebaum aufzunehmen.
** * Registriert ein neues Benutzerkonto. * @return bool * / public function register () if ($ this-> validate ()) $ user = $ this-> module-> manager-> createUser (['szenario' => 'register', 'email '=> $ this-> email,' username '=> $ this-> username,' password '=> $ this-> password,' role '=> 10, // User :: ROLE_USER;]); return $ user-> register (); falsch zurückgeben;
Schließlich in StatusController.php
, Wir fügen einige Bibliotheken und diese Zugriffsdefinitionen hinzu. Im folgenden Beispiel sind Aktualisierungsaktionen auf Moderatoren beschränkt, während Löschaktionen auf Administratoren beschränkt sind.
['class' => VerbFilter :: className (), 'actions' => ['delete' => ['post']],], 'access' => ['class' => AccessControl :: className ( ), // Wir überschreiben die Standardregelkonfiguration mit der neuen AccessRule-Klasse 'ruleConfig' => ['class' => AccessRule :: className (),], 'only' => ['index', 'create', 'Aktualisieren', 'Löschen'], 'Regeln' => [['Aktionen' => ['Index', 'Erstellen'], 'Erlauben' => true, // Erlaube Benutzern, Moderatoren und Administratoren das Erstellen von Rollen '=> [User :: ROLE_USER, User :: ROLE_MODERATOR, User :: ROLE_ADMIN],], [' actions '=> [' update '],' allow '=> true, // Moderatoren und Administratoren dürfen aktualisiert werden' rolls '=> [User :: ROLE_MODERATOR, User :: ROLE_ADMIN],], [' actions '=> [' delete '],' allow '=> true, // Admins dürfen Rollen löschen => [User :: ROLE_ADMIN],],],],];
Nun, wenn Sie sich ausloggen und die Status Über die Navigationsleiste gelangen Sie zum Anmeldebildschirm:
Wenn Sie sich anmelden, werden Sie erneut zur Indexansicht geleitet:
Wenn ich jedoch klicke Löschen, Ich werde diesen Zugriff verbotener Fehler erhalten, weil ich ein schwacher Benutzer und kein Administrator bin:
Wenn Sie sich zum Administrator erheben möchten, können Sie dies in der Datenbank tun. Ändern Sie die Rollenspalte der Benutzertabelle für Ihre user_id in 20 für Moderator und 30 für Administrator. Versuchen Sie, die Aktualisierungs- und Löschvorgänge erneut auszuführen. Je nach Ihrer gewählten Rolle werden Sie berechtigt sein.
Zugriffskontrollen sind eine der vielen Funktionen, die mich zu einem großen Befürworter des Yii-Frameworks machen. Yii macht mich zu einem viel effizienteren Entwickler, der Lösungen schneller als mit Vanilla PHP liefern kann.
Achten Sie auf kommende Tutorials in meiner Programmierreihe "Programmieren mit Yii2", während ich mich weiter mit verschiedenen Aspekten des Frameworks beschäftige. Vielleicht möchten Sie auch die Serie "Erstellen Sie Ihr Startup mit PHP" ausprobieren, die die erweiterte Vorlage von Yii2 verwendet, während ich eine Anwendung aus der realen Welt baue.
Wenn Sie wissen möchten, wann das nächste Yii2-Tutorial ankommt, folgen Sie mir @reifman auf Twitter oder besuchen Sie meine Instructor-Seite. Meine Ausbilderseite enthält alle Artikel dieser Serie, sobald sie veröffentlicht sind. Sie können mich auch per E-Mail auf meiner Lookahead Consulting-Website senden.