microdot.login — felhasználói bejelentkezési folyamat

Egy magasabb szintű burkoló a microdot.session köré, amely a hagyományos felhasználónév/jelszó alapú bejelentkezési folyamatot valósítja meg: egy user loader visszahívás a munkamenetben tárolt felhasználói azonosítót leképezi az alkalmazás felhasználói objektumára, az útvonal-dekorátorok a nem hitelesített kéréseket egy konfigurálható bejelentkezési URL-re irányítják, az opcionális „remember me” (emlékezz rám) sütik pedig lehetővé teszik, hogy a visszatérő látogatók a böngészőmenetek között is bejelentkezve maradjanak.

Megköveteli, hogy a microdot.session inicializálva legyen az alkalmazáson, mielőtt a login objektum létrejön – a munkamenet az, ahol a felhasználói azonosító tárolódik.

class Login

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

Az URL, amelyre a dekorátor a nem hitelesített kéréseket átirányítja. Az alkalmazás a tényleges bejelentkezési űrlapot/kezelőt biztosítja ezen az útvonalon. Alapértelmezett '/login'.

user_loader(f)

Dekorátor, amely regisztrálja a felhasználó-feloldó visszahívást. f a munkamenetben tárolt felhasználói azonosítót veszi, és visszaadja a felhasználói objektumot (vagy None értéket, ha az azonosító már nem érvényes – törölt fiók, visszavont munkamenet stb. esetén).

login = Login()

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

Egy útvonal Login példánnyal való dekorálása hitelesítés mögé zárja azt:

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

A nem hitelesített kérések a login_url címre irányulnak át egy ?next=<original-url> lekérdezési paraméterrel, így a bejelentkezési kezelő visszaküldheti a felhasználót oda, ahonnan érkezett.

fresh(f)

Hasonló a __call__() metódushoz, de elutasítja a „remember me” sütiből visszaállított munkameneteket – a felhasználónak az utolsó teljes bejelentkezés óta kifejezetten be kellett jelentkeznie. Érzékeny útvonalak (jelszóváltoztatás, fiók törlése) lezárására használatos, hogy egy ellopott remember-me süti ne férhessen hozzájuk.

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

Bejelentkezettként jelöli meg a user-t a request számára. Eltárolja a felhasználói azonosítót a munkamenetben, és visszaad egy átirányítási választ.

user

A felhasználó-betöltő által visszaadott felhasználói objektum. Rendelkeznie kell egy id attribútummal.

remember

Ha igaz értékű, egy hosszú élettartamú _remember sütit is beállít. Adj át True értéket az alapértelmezett 30 naphoz, vagy egy egész számot annak megadásához, hogy a süti hány napig maradjon érvényes.

redirect_url

Hová irányítson át a bejelentkezés után. Felülírja az eredeti kérésből származó ?next=<url>, ha az egy azonos oldalon (same-site) belüli útvonalra mutat.

Visszaadja az átirányítási választ – add vissza ennek értékét a bejelentkezési útvonal kezelőjéből.

async logout_user(request)

Törli a felhasználói azonosítót a munkamenetből, és eltávolít minden _remember sütit. Használd egy /logout útvonalról:

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

Visszaadja az éppen bejelentkezett felhasználói objektumot (vagy None értéket). A request.g.current_user attribútumon memoizálódik, így az egy kérésen belüli ismételt hívások csak egyszer érintik a betöltőt.

Példa

Egy minimális bejelentkezési folyamat:

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

A _remember süti maga egy aláírt JWT (a munkamenet titkos kulcsát használva), így egy ellopott süti nem használható fel újra egy másik alkalmazáson vagy a titkos kulcs cseréje után.