microdot.login — flusso di login utente¶
Un wrapper di livello superiore attorno a microdot.session che implementa il flusso di login convenzionale con nome utente / password: un callback user loader mappa l’id utente memorizzato nella sessione all’oggetto utente dell’applicazione, i decoratori di route reindirizzano le richieste non autenticate a un URL di login configurabile, e i cookie «remember me» opzionali consentono ai visitatori che ritornano di rimanere autenticati tra le sessioni del browser.
Richiede che microdot.session sia inizializzato sull’applicazione prima che venga costruito l’oggetto login – la sessione è il punto in cui viene memorizzato l’id utente.
class Login¶
- class microdot.login.Login(login_url: str = '/login')¶
- login_url
URL a cui il decoratore reindirizza le richieste non autenticate. L’applicazione fornisce il form/handler di login effettivo su questa route. Predefinito
'/login'.
- user_loader(f)¶
Decoratore che registra il callback di risoluzione utente. f riceve l’id utente memorizzato nella sessione e restituisce l’oggetto utente (oppure
Nonese l’id non è più valido – un account eliminato, una sessione revocata, ecc.).login = Login() @login.user_loader async def load_user(user_id): return users.get(user_id)
- __call__(f)¶
Decorare una route con l’istanza
Loginla protegge dietro l’autenticazione:@app.get('/dashboard') @login async def dashboard(request): user = request.g.current_user # ...
Le richieste non autenticate vengono reindirizzate a login_url con un parametro di query
?next=<original-url>in modo che l’handler di login possa rimandare l’utente da dove proveniva.
- fresh(f)¶
Come
__call__(), ma rifiuta le sessioni ripristinate da un cookie «remember me» – l’utente deve aver effettuato esplicitamente il login dall’ultimo login completo. Utilizzato per proteggere le route sensibili (cambio password, eliminazione account) in modo che un cookie remember-me rubato non possa raggiungerle.
- async login_user(request, user, remember: bool | int = False, redirect_url: str = '/')¶
Contrassegna user come autenticato per request. Memorizza l’id utente nella sessione e restituisce una risposta di reindirizzamento.
- user
L’oggetto utente restituito dallo user loader. Deve avere un attributo
id.- remember
Se truthy, imposta anche un cookie
_rememberdi lunga durata. PassaTrueper i 30 giorni predefiniti, oppure un intero per il numero di giorni di durata del cookie.- redirect_url
Dove reindirizzare dopo il login. Sovrascritto da
?next=<url>della richiesta originale se punta a un percorso same-site.
Restituisce la risposta di reindirizzamento – restituisci il suo valore dall’handler della route di login.
- async logout_user(request)¶
Rimuove l’id utente dalla sessione ed elimina qualsiasi cookie
_remember. Da utilizzare da una route/logout@app.post('/logout') async def logout(request): await login.logout_user(request) return redirect('/')
- async get_current_user(request)¶
Restituisce l’oggetto dell’utente attualmente autenticato (oppure
None). Memoizzato surequest.g.current_userin modo che chiamate ripetute all’interno di una stessa richiesta accedano al loader una sola volta.
Esempio¶
Un flusso di login minimale:
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('/')
Il cookie _remember è esso stesso un JWT firmato (usando il segreto della sessione), quindi un cookie rubato non può essere riutilizzato su un’applicazione diversa né dopo che il segreto è stato ruotato.