User Login und Logout
Wir wollen den generierten Usern jetzt ermöglich, sich auf der Website einzuloggen. Ein vollständiger Authentifikationsprozess beinhaltet natürlich noch euch eine Registrierung.
Django auth
Django installiert die Authentifizierungs-App automatisch, wenn ein neues
Projekt erstellt wird. In der Datei
event_manager/settings/base.py
unter den INSTALLED_APPS
sehen wir, dass
django.contrib.auth
eine von mehreren integrierten Apps ist, die Django für
uns installiert hat. Die Auth-Applikation bietet Views und URLs für die
wichtigsten Authentifizierungs-Aufgaben wie login, logout oder Passwort ändern.
Nur die Templates dazu müssen wir selber anlegen.
INSTALLED_APPS = [
'user',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Um die Auth-App zu nutzen, müssen wir diese auf Projektebene verlinken, dh. zu
den event_manager/event_manager/urls.py
hinzufügen.
path('accounts/', include('django.contrib.auth.urls')),
from django.conf import settings
from django.contrib import admin
from django.urls import include, path
from django.views.generic.base import RedirectView
urlpatterns = [
path("", RedirectView.as_view(url="events")),
path("admin/doc/", include("django.contrib.admindocs.urls")),
path("i18n/", include("django.conf.urls.i18n")),
path("admin/", admin.site.urls),
path("events/", include("events.urls", namespace="events")),
path('accounts/', include('django.contrib.auth.urls')),
]
if settings.DEBUG:
import debug_toolbar
urlpatterns = [
path("__debug__/", include(debug_toolbar.urls)),
] + urlpatterns
Die jetzt eingebundene Authentifizierungs-App bietet uns mehrere Authentifizierungsansichten und URLs für die Anmeldung, Abmeldung und Passwortverwaltung.
Die Standar-Urls der Auth-App
Out of the box bietet uns die Auth-App folgende URLs für die wichtigsten Aktionen:
accounts/login/ [name=‘login‘]
accounts/logout/ [name=‘logout‘]
accounts/password_change/ [name=‘password_change‘]
accounts/password_change/done/ [name=‘password_change_done‘]
accounts/password_reset/ [name=‘password_reset‘]
accounts/password_reset/done/ [name=‘password_reset_done‘]
accounts/reset/<uidb64>/<token>/ [name=‘password_reset_confirm‘]
accounts/reset/done/ [name=‘password_reset_complete‘]
Die URLs sollten selbsterklärend sein. Bei Eingabe der URL accounts/login
landet man folglicherweise auf einer Login-Maske, um sich am System anzumelden.
Allerdings benötigen wir noch Templates und das Einrichten der URLs, um diese
Aktionen zu ermöglichen.
Urls anpassen
Der Default-Urlpfad für die Login-App ist accounts
. Falls man damit
zufrieden ist, braucht man nichts weiter zu tun. Möchte man aber eine andere
URL für den Login nutzen, zum Beispiel http://127.0.0.1:8000/user/login
,
dann muss man diesen Pfad in den Settings festlegen:
LOGIN_URL = "/user/login"
sowie in den event_manager/event_manager/urls.py
die URLs zur Auth-App
anpassen:
path("user/", include("django.contrib.auth.urls")),
Django sorgt dann selbständig dafür, dass bei dem Versuch, eine Aktion
auszuführen, die eine Anmeldung benötigt, an die entsprechene URL
weitergeleitet wird. Standardmäßig ist das wie gesagt accounts/login
.
Views
Für die Standard-Aufgaben login
, logout
und password_change
benötigen wir keine weiteren Views, diese werden von Django selber gestellt.
Templates für die Login Page
Wir müssen jetzt die Templates für die Views erstellen. Dazu legen wir in den
Projekt-Templates unter user/templates/
ein neues Verzeichnis
namens registration
an. Django erwartet den Pfad registration
innerhalb eines der Templates-Suchpfade, die wir in den Settings angelegt
haben. Das beinhaltet auch die App user
.
So sieht das User-Verzeichnis aktuell aus:
└── user
├── admin.py
├── apps.py
├── factories.py
├── forms.py
├── __init__.py
├── management
│ └── commands
├── migrations
├── models.py
├── templates
│ └── registration
├── urls.py
└── views.py
Nun legen wird dort das Template für die Login-Seite an:
event_manager/user/templates/registration/login.html
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
<main class="form-signin">
<form method="post">
<img class="mb-4" src="{% static 'penglogo.png' %}" alt="" >
<h1 class="h3 mb-3 fw-normal">Bitte einloggen</h1>
{% csrf_token %}
{{ form|crispy }}
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Erinnere Dich
</label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2019–2022</p>
</form>
</main>
{% endblock %}
in den Settings müssen wir jetzt noch spezifizieren, wohin nach erfolgreichem
Einloggen bzw. Ausloggen weitergeleitet wird. Per default werden wir auf das UserProfil
weitergeleitet, was aber noch gar nicht implementiert ist.
Wir wollen aber nach Login auf die Hauptseite umgeleitet werden.
in den event_manager/settings/base.py
legen wir diese Konstante an.
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'
Verlinkungen in der Base-Datei anpassen
Bisher konnten wir die Verlinkungen in der Top-Navigation nicht nutzen, zum Beispiel den Logout und Login. Das wollen wir jetzt nachholen und verändern die
event_manager/templates/base.html
. Wir müssen nur die Auskommentierten Zeilen wieder einkommentieren
<li>
<a class="dropdown-item" href="{% url 'password_change' %}">Passwort ändern</a>
</li>
<li>
<a class="dropdown-item" href="{% url 'logout' %}">Sign out</a>
</li>
Passwort ändern
Wir wollen noch eine Passwort ändern Seite hinzufügen:
Im Verzeichnis event_manager/user/templates/registration
legen wir zwei Dateien
an: password_change_form.html
und password_change_done.html
Das password_change_done
-Formular sieht so aus:
{% extends 'base.html' %}
{% block head%}
Passwort erfolgreich geändert!
{% endblock %}
{% block content %}
Gratulation! Das Passwort wurde erfolgreich geändert!
<a href="{% url 'events:events' %}">Zur Übersichtsseite</a>
{% endblock %}
Das password_change_form
-Formular sieht so aus:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block head%}
Log in
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Passwort ändern</button>
</form>
{% endblock %}
Wenn wir jetzt im eingeloggten Zustand die URL
http://127.0.0.1:8000/accounts/password_change
besuchen, sehen wir das
Passwort-Ändern-Formular.
Eingeloggt das Login-Formular aufrufen
Einen kleinen Schönheitsfehler hat unser Login aber noch: wir können auch im
eingeloggten Zustand die http://127.0.0.1:8000/accounts/login/
aufrufen.
Besser wäre es, wenn das Login-Formular nur dann aufrufbar wäre, wenn wir nicht
eingeloggt sind. Es müsste also sowas wie eine Weiterleitung geben.
Um dieses Problem kümmern wir uns im Kapitel „Registrierung“.