Die Funktionalität der Applikation ist vollständig. Leider kann jedoch jede Person Bücher leihen und wieder zurückgeben. Die Applikation soll dementsprechend ausgebaut werden, dass jeder die Liste der Bücher einsehen kann, jedoch nur eingeloggte Personen Bücher leihen und wieder zurückgeben können. Dabei sind die Nutzer der Applikation die Entleiher, die innerhalb der Applikation schon durch eine Klasse repräsentiert sind, der Entleiher
-Klasse. Die Entleiher.php
wird wie folgt erweitert, dass diese das Interface UserInterface
implementiert:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
use Symfony\Component\Security\Core\User\UserInterface; // ... class Entleiher implements UserInterface // ... public function getRoles() { $roles[] = 'ROLE_USER'; return array_unique($roles); } /** * {@inheritdoc} */ public function getSalt() { return null; } /** * {@inheritdoc} */ public function eraseCredentials() {} |
Die Klasse implementiert nun eine Funktion getRoles()
. Symfony macht es möglich, mehrere Benutzerrollen zu definieren, die unterschiedliche Zugriffsrechte auf eine Web-Applikation besitzen. In diesem Beispiel wird jedoch nur die Rolle ROLE_USER
genutzt, weshalb die Rolle nicht zusammen mit den Benutzern in der Datenbank abgelegt werden muss, sondern hier statisch definiert werden darf. Die Methode getSalt()
gibt eine Ausgangszahl für den Hashingmechanismus für das Passwort an. Der gleich genutzte Hashingmechanismus benötigt jedoch kein Salt, weshalb hier null
zurückgegeben werden kann. Mit der Funktion eraseCredentials()
soll es schließlich möglich sein, vorhergehende Credentials wieder zu entfernen. Da diese Applikation direkt mit einem verschlüsselten Passwort startet, kann diese Funktion leer gelassen werden.
Welche Security-Regeln Symfony anwenden soll ist innerhalb der Datei security.yml
in dem Verzeichnis \app\config\
zu finden. Diese wird wie folgt erweitert:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
security: encoders: AppBundle\Entity\Entleiher: algorithm: bcrypt providers: entleiher_db_provider: entity: class: AppBundle:Entleiher property: username firewalls: # Für den Developer-Modus dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: ~ http_basic: ~ provider: entleiher_db_provider access_control: - { path: ^/leihen, roles: ROLE_USER } - { path: ^/zurueckgeben, roles: ROLE_USER } |
Unter encoders
wird festgelegt, dass BCrypt als Passworthashingmechanismus verwendet werden soll. Unter providers
wird festgelegt, welche Entity die Benutzerinformationen beinhaltet. Es ist die Klasse AppBundle:Entleiher
und der Nutzername ist in der property
namens username
hinterlegt.
Innerhalb des Blockes firewalls
wird zunächst eine Öffnung der Firewall im Developer-Modus für die Developer-Tools von Symfony definiert. Im main
-Bereich wird definiert, dass der anonyme Nutzer zunächst zugelassen ist. Wenn eine URL innerhalb von access_control
aufgelistet ist, wird eine HTTP-Basic Authentifizierung durchgeführt und zwar mit Hilfe den Benutzerdaten die innerhalb des oben definierten Providers entleiher_db_provider
verfügbar sind.
Entleihen und Rückgabe sind nun für unangemeldete Nutzer nicht mehr möglich. Leider ist es auch nicht mehr möglich, sich in die Applikation einzuloggen. Innerhalb der Datenbank muss das Passwort verschlüsselt abgelegt werden. Dazu muss das Wunschpasswort zunächst verschlüsselt werden. Die Applikation verfügt momentan noch über keine Benutzerverwaltung. Diese könnte als Übung hinzugefügt werden. Der folgende Codeblock, der beispielsweise einfach in die indexAction()
des BuchController
s eingefügt werden könnte, legt das verschlüsselte Passwort test
in der Datenbank für einen Nutzer mustermann
ab:
1 2 3 4 5 6 7 8 9 10 11 |
$benutzer = $this->getDoctrine() ->getRepository(Entleiher::class) ->findOneByUsername('mustermann'); $unkodiertesPasswort = 'test'; $enkoder = $this->container ->get('security.password_encoder'); $enkodiertesPasswort = $enkoder->encodePassword($benutzer, $unkodiertesPasswort); $benutzer->setPassword($enkodiertesPasswort); $manager = $this->getDoctrine()->getManager(); $manager->persist($benutzer); $manager->flush(); |
Eine Funktionalität wurde bisher nicht beschrieben, die dem aufmerksamen Leser vielleicht nicht entgangen ist: Mit Hilfe der Funktion $this->getUser()
wird innerhalb eines Kontrollers, der von der Controller
-Klasse erbt, der aktuelle Benutzer bereitgestellt. Diese Funktion wurde beim Leihen eines Buches verwendet, um den aktuell leihenden Nutzer in der Datenbank zu hinterlegen.