microdot.login — gebruikersinlogproces

Een wrapper op hoger niveau rond microdot.session die het conventionele inlogproces met gebruikersnaam / wachtwoord implementeert: een callback voor het laden van de gebruiker koppelt de in de sessie opgeslagen gebruikers-id terug naar het gebruikersobject van de applicatie, route-decorators leiden niet-geauthenticeerde verzoeken om naar een instelbare login-URL, en optionele “onthoud mij”-cookies laten terugkerende bezoekers ingelogd blijven over browsersessies heen.

Vereist dat microdot.session op de applicatie is geïnitialiseerd voordat het login-object wordt geconstrueerd – de sessie is waar de gebruikers-id wordt opgeslagen.

class Login

class microdot.login.Login(login_url: str = '/login')
login_url

URL waarnaar de decorator niet-geauthenticeerde verzoeken omleidt. De applicatie levert het daadwerkelijke inlogformulier/de handler op deze route. Standaard '/login'.

user_loader(f)

Decorator die de callback voor het oplossen van de gebruiker registreert. f neemt de in de sessie opgeslagen gebruikers-id aan en retourneert het gebruikersobject (of None als de id niet langer geldig is – een verwijderd account, een ingetrokken sessie, enz.).

login = Login()

@login.user_loader
async def load_user(user_id):
    return users.get(user_id)
__call__(f)

Een route voorzien van de Login-instantie als decorator schermt deze af achter authenticatie:

@app.get('/dashboard')
@login
async def dashboard(request):
    user = request.g.current_user
    # ...

Niet-geauthenticeerde verzoeken worden omgeleid naar login_url met een ?next=<original-url>-queryparameter, zodat de inloghandler de gebruiker terug kan sturen naar waar deze vandaan kwam.

fresh(f)

Net als __call__(), maar weigert sessies die hersteld zijn uit een “onthoud mij”-cookie – de gebruiker moet sinds de laatste volledige login expliciet zijn ingelogd. Wordt gebruikt om gevoelige routes af te schermen (wachtwoordwijziging, accountverwijdering) zodat een gestolen onthoud-mij-cookie deze niet kan bereiken.

async login_user(request, user, remember: bool | int = False, redirect_url: str = '/')

Markeer user als ingelogd voor request. Slaat de gebruikers-id op in de sessie en retourneert een omleidingsantwoord.

user

Het gebruikersobject dat door de gebruikerslader is geretourneerd. Moet een id-attribuut hebben.

remember

Indien waar (truthy), stel ook een langlevende _remember-cookie in. Geef True op voor de standaard 30 dagen, of een geheel getal voor het aantal dagen dat de cookie moet blijven bestaan.

redirect_url

Waarheen om te leiden na het inloggen. Wordt overschreven door ?next=<url> uit het oorspronkelijke verzoek als dit naar een same-site-pad verwijst.

Retourneert het omleidingsantwoord – retourneer de waarde ervan vanuit de handler van de login-route.

async logout_user(request)

Wis de gebruikers-id uit de sessie en verwijder een eventuele _remember-cookie. Gebruik vanuit een /logout-route:

@app.post('/logout')
async def logout(request):
    await login.logout_user(request)
    return redirect('/')
async get_current_user(request)

Retourneer het momenteel ingelogde gebruikersobject (of None). Wordt gememoïseerd op request.g.current_user zodat herhaalde aanroepen binnen één verzoek de lader slechts eenmaal raken.

Voorbeeld

Een minimaal inlogproces:

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('/')

De _remember-cookie is zelf een ondertekend JWT (met het geheim van de sessie), zodat een gestolen cookie niet hergebruikt kan worden op een andere applicatie of nadat het geheim is geroteerd.