Mit dem Authentication-Generator lässt sich eine bestehende Rails-Anwendung um eine einfache Benutzeranmeldung erweitern.
Neben Login und Logout unterstützt der Generator auch die Registrierung neuer Benutzer und kann ausgewählte Controller vor nicht angemeldeten Besuchern schützen.
Seit b4um Generators 0.2.8 wurde der Self-Service-Bereich der Authentifizierung erweitert: Neue Benutzer können sich über die Navigation registrieren und werden nach erfolgreicher Registrierung direkt angemeldet. Das eigene Benutzerkonto wird dabei als privates Profil behandelt.
In diesem Tutorial verwenden wir ein User-Modell für die Authentifizierung und schützen zusätzlich die schreibenden Aktionen unseres ProductsController.
Voraussetzungen
Für dieses Tutorial verwenden wir b4um Generators 0.2.8 oder neuer.
Im Gemfile kann die Version beispielsweise so angegeben werden:
gem "b4um_generators", "~> 0.2.8"
Anschließend werden die Abhängigkeiten installiert bzw. aktualisiert:
bundle install
Für die Authentifizierung benötigen wir außerdem ein bereits vorhandenes User-Modell mit has_secure_password. Dazu gehört ein password_digest-Feld in der Datenbank sowie bcrypt im Projekt.
In unserer Beispielanwendung existieren außerdem bereits Users und Products. Auf dieser Grundlage erzeugen wir im nächsten Schritt die Authentifizierung.
User für die Authentifizierung erstellen
Der Authentication-Generator setzt ein bereits vorhandenes Benutzer-Modell voraus. Deshalb erstellen wir zunächst einen User mit dem b4um Scaffold-Generator.
Für unser Beispiel benötigt der User einen Namen, eine E-Mail-Adresse und ein Passwort:
bin/rails generate b4um:scaffold User \
name:string \
email:string \
password_digest:string
Das Feld password_digest erkennt der Generator als Grundlage für die Passwort-Authentifizierung und richtet has_secure_password entsprechend ein.
bcrypt wurde bereits über den b4um Installer eingerichtet. Zusätzliche Änderungen am Gemfile sind deshalb an dieser Stelle nicht erforderlich.
Anschließend führen wir die Migration aus:
bin/rails db:migrate
Damit ist unser User für die Authentifizierung vorbereitet.
Authentication-Generator ausführen
Wir möchten User als Authentication-Modell verwenden und gleichzeitig die schreibenden Aktionen von Productsschützen:
bin/rails generate b4um:authentication User --protect=Products
Der Generator richtet die Session-Authentifizierung ein, passt das Benutzerprofil und die Navigation an und ergänzt den Zugriffsschutz für den angegebenen Controller.
Terminal
Nach dem Generatorlauf sehen ausgeloggte Besucher in der Navigation neben Login jetzt auch Register.
2b.webp
68 KB
Benutzer registrieren
Über Register in der Navigation gelangen wir zur Registrierungsseite unter /users/new.
Das Formular stammt aus unserem vorhandenen User-Scaffold. In unserem Beispiel kann der neue Benutzer seinen Namen, seine E-Mail-Adresse sowie ein Passwort mit Passwortbestätigung eingeben.
/users/new
Mit Create User wird der neue Benutzer angelegt.
Seit Version 0.2.8 endet der Ablauf an dieser Stelle nicht mehr bei einem unangemeldeten Benutzer. Nach erfolgreicher Registrierung setzt die Authentication automatisch die Session für den gerade angelegten Benutzer.
Der Benutzer wird dadurch unmittelbar angemeldet und auf sein eigenes Profil weitergeleitet.
Erfolgreiche Registrierung und automatisch angemeldeter Benutzer
In unserem Beispiel erkennen wir den erfolgreichen Ablauf an mehreren Stellen:
Die Meldung „User was successfully created.“ bestätigt die erfolgreiche Registrierung.
Die Anwendung zeigt anschließend das Profil des neu angelegten Benutzers.
Register und Login sind aus der Navigation verschwunden.
Stattdessen stehen jetzt Profile und Logout zur Verfügung.
Eine zusätzliche Anmeldung direkt nach der Registrierung ist damit nicht erforderlich.
Was der Generator dafür ergänzt
Beim Authentication-Modell ergänzt der Generator nach erfolgreichem Speichern die Session-Zuweisung:
if @user.save
session[:user_id] = @user.id
# ...
end
Damit weiß die Anwendung unmittelbar nach der Registrierung, welcher Benutzer angemeldet ist.
Der Authentication-Generator verwendet dabei den angegebenen Modellnamen. In unserem Beispiel ist das User; deshalb wird session[:user_id] verwendet.
Das eigene Benutzerkonto als Profil
Nach der Anmeldung erscheint in der Navigation nicht mehr ein allgemeiner Link auf die Benutzerverwaltung, sondern Profile.
Der Link führt direkt zum aktuell angemeldeten Benutzer.
Das ist bewusst so vorgesehen: Bei einer normalen Self-Service-Anmeldung soll ein Benutzer sein eigenes Konto verwalten können, aber nicht automatisch Zugriff auf die Profile aller anderen Benutzer erhalten.
Auch der direkte Aufruf von:
/users
zeigt deshalb für einen normalen angemeldeten Benutzer keine Benutzerliste an. Stattdessen wird er auf sein eigenes Profil weitergeleitet.
Fremde Benutzerprofile schützen
Ein angemeldeter Benutzer darf nur auf sein eigenes Profil zugreifen.
Auch wenn die ID eines anderen Benutzers bekannt ist und beispielsweise /users/5 direkt in die Adresszeile eingegeben wird, verhindert die Authentication den Zugriff.
Zugriff auf ein fremdes Benutzerprofil wird mit „Access denied.“ abgewiesen
Der Generator ergänzt dafür eine Prüfung im UsersController:
def require_current_user
return if @user == current_user
redirect_to root_path, alert: "Access denied."
end
Diese Prüfung wird für die Aktionen show, edit, update und destroy ausgeführt:
before_action :require_current_user,
only: %i[ show edit update destroy ]
Damit kann ein angemeldeter Benutzer sein eigenes Profil anzeigen, bearbeiten oder löschen, aber nicht einfach durch Ändern der ID auf das Konto eines anderen Benutzers zugreifen.
Wird ein fremdes Profil aufgerufen, erfolgt die Weiterleitung auf die Startseite mit der Meldung „Access denied.“.
Controller mit --protect schützen
Beim Aufruf des Authentication-Generators haben wir zusätzlich Products angegeben:
bin/rails generate b4um:authentication User --protect=Products
Mit --protect=Products schützt der Generator die Aktionen des ProductsController, mit denen Daten angelegt, verändert oder gelöscht werden.
Die Aktionen index und show bleiben dagegen öffentlich erreichbar. Besucher können Produkte also weiterhin ansehen, ohne sich vorher anmelden zu müssen.
Damit benötigen insbesondere new, create, edit, update und destroy eine Anmeldung.
Ruft ein nicht angemeldeter Besucher beispielsweise direkt
/products/new
auf, wird das Formular nicht angezeigt. Stattdessen erfolgt die Weiterleitung zur Login-Seite.
Aufruf von /products/new ohne Anmeldung – Weiterleitung zum Login mit „Please log in first.“
Nach erfolgreicher Anmeldung stehen die geschützten Aktionen wieder zur Verfügung.
Geschützte Aktionen nach der Anmeldung
Nach erfolgreicher Anmeldung kann der Benutzer die geschützten Aktionen wieder aufrufen.
Auf der Products-Seite erscheint für den angemeldeten Benutzer beispielsweise wieder die Möglichkeit, ein neues Produkt anzulegen.
Products-Seite nach der Anmeldung mit „New product“ sowie „Profile“ und „Logout“ in der Navigation
Über New product lässt sich anschließend das zuvor geschützte Formular öffnen.
Formular zum Anlegen eines neuen Produkts als angemeldeter Benutzer
Der Zugriffsschutz betrifft damit nicht die öffentlich sichtbaren Inhalte der Anwendung. Besucher können index und show weiterhin aufrufen, während Änderungen an den Daten eine Anmeldung voraussetzen.
So lässt sich mit --protect auf einfache Weise eine typische Trennung zwischen öffentlich lesbaren und nur für angemeldete Benutzer verfügbaren Aktionen einrichten.
Logout und erneute Anmeldung
Ist ein Benutzer angemeldet, zeigt die Navigation Profile und Logout an. Die Links Register und Login werden in diesem Zustand nicht angezeigt.
Über Logout wird die aktuelle Session beendet. Anschließend wechselt die Navigation wieder zu Register und Login.
Bereits registrierte Benutzer können sich über Login erneut mit ihrer E-Mail-Adresse und ihrem Passwort anmelden.
Der Authentication-Generator stellt dafür die Session-Routen bereit:
get "login", to: "sessions#new", as: :login
post "login", to: "sessions#create"
delete "logout", to: "sessions#destroy", as: :logout
Bei erfolgreicher Anmeldung wird die ID des Authentication-Benutzers in der Session gespeichert. Dadurch steht der Benutzer anschließend über current_user zur Verfügung.
Beim Logout wird diese Session wieder entfernt.
Die Navigation passt sich automatisch an den jeweiligen Zustand an:
Ausgeloggt: Register und Login
Eingeloggt: Profile und Logout
Damit ist der grundlegende Ablauf aus Registrierung, Anmeldung, geschütztem Profil und Logout vollständig eingerichtet.
Eigenes Benutzerkonto löschen
Da das Authentication-Modell als persönliches Profil behandelt wird, kann ein angemeldeter Benutzer auch sein eigenes Konto löschen, sofern das vorhandene User-Scaffold diese Aktion anbietet.
Der Zugriff auf destroy ist – genau wie show, edit und update – auf den aktuell angemeldeten Benutzer beschränkt. Ein Benutzer kann daher nicht das Konto eines anderen Benutzers über dessen ID löschen.
Wird das eigene Konto gelöscht, entfernt die Authentication außerdem die zugehörige Session:
def clear_authentication_session
session.delete(:user_id)
end
Nach erfolgreichem Löschen erfolgt die Weiterleitung auf die Startseite. Der gelöschte Benutzer gilt anschließend nicht mehr als angemeldet.
Damit wird verhindert, dass nach dem Löschen des Authentication-Datensatzes eine Session bestehen bleibt, die noch auf einen nicht mehr vorhandenen Benutzer verweist.
Zusammenfassung
In diesem Tutorial haben wir die Grundlage für eine Benutzeranmeldung erstellt und unsere Rails-Anwendung anschließend mit dem Authentication-Generator um Registrierung, Login und geschützte Bereiche erweitert.
Dazu haben wir:
mit dem b4um Scaffold-Generator einen User mit name, email und password_digest erstellt,
die dazugehörige Datenbankmigration ausgeführt,
User als Authentication-Modell eingerichtet,
eine Registrierung über Register ermöglicht,
neue Benutzer nach erfolgreicher Registrierung automatisch angemeldet,
das eigene Benutzerkonto als privates Profile geschützt,
den Zugriff auf fremde Benutzerprofile verhindert,
die allgemeine Benutzerübersicht für normale Benutzer gesperrt,
mit --protect=Products die schreibenden Product-Aktionen geschützt,
index und show weiterhin öffentlich zugänglich gelassen,
Login und Logout eingerichtet
und die Session beim Löschen des eigenen Benutzerkontos beendet.
Für die Vorbereitung des Benutzers haben wir zunächst das Scaffold erzeugt:
bin/rails generate b4um:scaffold User \
name:string \
email:string \
password_digest:string
Anschließend haben wir die Authentifizierung eingerichtet:
bin/rails generate b4um:authentication User --protect=Products
Die in diesem Tutorial verwendeten Self-Service-Funktionen stehen ab b4um Generators 0.2.8 zur Verfügung.
Damit haben wir eine Grundlage für Anwendungen geschaffen, in denen sich Benutzer selbst registrieren, anmelden und ihr eigenes Profil verwalten können, während ausgewählte Aktionen nur angemeldeten Benutzern zur Verfügung stehen.
Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren,
Funktionen für soziale Medien anbieten zu können und die Zugriffe auf
unsere Website zu analysieren.
Sie akzeptieren unsere Cookies, wenn Sie fortfahren diese Webseite zu
nutzen.
Datenschutzerklärung.