microdot.login — Benutzeranmeldungsablauf¶
Ein übergeordneter Wrapper um microdot.session, der den herkömmlichen Anmeldungsablauf mit Benutzername / Passwort implementiert: ein user loader-Callback bildet die in der Session gespeicherte Benutzer-ID auf das Benutzerobjekt der Anwendung ab, Routen-Dekoratoren leiten nicht authentifizierte Anfragen auf eine konfigurierbare Login-URL um, und optionale „Remember me“-Cookies lassen wiederkehrende Besucher über Browser-Sitzungen hinweg angemeldet bleiben.
Erfordert, dass microdot.session in der Anwendung initialisiert ist, bevor das Login-Objekt erzeugt wird – in der Session wird die Benutzer-ID gespeichert.
class Login¶
- class microdot.login.Login(login_url: str = '/login')¶
- login_url
URL, auf die der Dekorator nicht authentifizierte Anfragen umleitet. Die Anwendung stellt das eigentliche Login-Formular / den Handler unter dieser Route bereit. Standard
'/login'.
- user_loader(f)¶
Dekorator, der den Benutzer-Resolver-Callback registriert. f erhält die in der Session gespeicherte Benutzer-ID und gibt das Benutzerobjekt zurück (oder
None, wenn die ID nicht mehr gültig ist – ein gelöschtes Konto, eine widerrufene Session usw.).login = Login() @login.user_loader async def load_user(user_id): return users.get(user_id)
- __call__(f)¶
Das Dekorieren einer Route mit der
Login-Instanz stellt sie hinter eine Authentifizierung:@app.get('/dashboard') @login async def dashboard(request): user = request.g.current_user # ...
Nicht authentifizierte Anfragen werden mit einem Abfrageparameter
?next=<original-url>auf login_url umgeleitet, sodass der Login-Handler den Benutzer dorthin zurücksenden kann, wo er hergekommen ist.
- fresh(f)¶
Wie
__call__(), lehnt aber Sessions ab, die aus einem „Remember me“-Cookie wiederhergestellt wurden – der Benutzer muss sich seit dem letzten vollständigen Login ausdrücklich angemeldet haben. Wird verwendet, um sensible Routen (Passwortänderung, Kontolöschung) abzusichern, damit ein gestohlener Remember-me-Cookie sie nicht erreichen kann.
- async login_user(request, user, remember: bool | int = False, redirect_url: str = '/')¶
Markiert user für request als angemeldet. Speichert die Benutzer-ID in der Session und gibt eine Weiterleitungsantwort zurück.
- user
Das vom User-Loader zurückgegebene Benutzerobjekt. Muss ein
id-Attribut haben.- remember
Wenn wahr, wird außerdem ein langlebiger
_remember-Cookie gesetzt. ÜbergibTruefür die standardmäßigen 30 Tage oder eine ganze Zahl für die Anzahl der Tage, die der Cookie bestehen soll.- redirect_url
Wohin nach dem Login umgeleitet werden soll. Wird durch
?next=<url>aus der ursprünglichen Anfrage überschrieben, wenn es auf einen Same-Site-Pfad verweist.
Gibt die Weiterleitungsantwort zurück – gib ihren Wert aus dem Login-Routen-Handler zurück.
- async logout_user(request)¶
Entfernt die Benutzer-ID aus der Session und löscht jeden
_remember-Cookie. Aus einer/logout-Route verwenden:@app.post('/logout') async def logout(request): await login.logout_user(request) return redirect('/')
- async get_current_user(request)¶
Gibt das aktuell angemeldete Benutzerobjekt zurück (oder
None). Wird inrequest.g.current_usermemoisiert, sodass wiederholte Aufrufe innerhalb einer Anfrage den Loader nur einmal erreichen.
Beispiel¶
Ein minimaler Anmeldungsablauf:
from microdot import Microdot, redirect
from microdot.session import Session
from microdot.login import Login
app = Microdot()
Session(app, secret_key=load_secret())
login = Login()
@login.user_loader
async def load_user(user_id):
return users.get(user_id)
@app.get('/login')
async def login_page(request):
return Response.send_file('static/login.html')
@app.post('/login')
async def do_login(request):
user = authenticate(request.form['user'], request.form['pass'])
if not user:
return redirect('/login?error=1')
return await login.login_user(request, user, remember=True)
@app.get('/dashboard')
@login
async def dashboard(request):
return 'hi ' + request.g.current_user.name
@app.post('/logout')
async def logout(request):
await login.logout_user(request)
return redirect('/')
Der _remember-Cookie ist selbst ein signiertes JWT (mithilfe des Session-Geheimnisses), sodass ein gestohlener Cookie nicht in einer anderen Anwendung oder nach einer Rotation des Geheimnisses wiederverwendet werden kann.