microdot.login — tijek prijave korisnika

Omotač više razine oko microdot.session koji implementira uobičajeni tijek prijave putem korisničkog imena / lozinke: povratni poziv user loader preslikava pohranjeni korisnički ID iz sesije natrag u korisnički objekt aplikacije, dekoratori rute preusmjeravaju neautenticirane zahtjeve na podesivu URL adresu za prijavu, a opcionalni kolačići „zapamti me” omogućuju povratnim posjetiteljima da ostanu prijavljeni između sesija preglednika.

Zahtijeva da microdot.session bude inicijaliziran na aplikaciji prije konstruiranja login objekta – sesija je mjesto gdje se pohranjuje korisnički ID.

class Login

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

URL na koji dekorator preusmjerava neautenticirane zahtjeve. Aplikacija pruža stvarni obrazac/rukovatelja za prijavu na ovoj ruti. Zadano '/login'.

user_loader(f)

Dekorator koji registrira povratni poziv za razrješavanje korisnika. f prima korisnički ID pohranjen u sesiji i vraća korisnički objekt (ili None ako ID više nije valjan – obrisani račun, opozvana sesija itd.).

login = Login()

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

Dekoriranje rute instancom Login štiti je iza autentifikacije:

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

Neautenticirani zahtjevi preusmjeravaju se na login_url s upitnim parametrom ?next=<original-url> kako bi rukovatelj prijave mogao vratiti korisnika tamo odakle je došao.

fresh(f)

Poput __call__(), ali odbija sesije obnovljene iz kolačića „zapamti me” – korisnik se mora izričito prijaviti od posljednje potpune prijave. Koristi se za zaštitu osjetljivih ruta (promjena lozinke, brisanje računa) tako da ukradeni kolačić zapamti-me ne može doprijeti do njih.

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

Označava user kao prijavljenog za request. Pohranjuje korisnički ID u sesiju i vraća odgovor preusmjeravanja.

user

Korisnički objekt vraćen od user loadera. Mora imati atribut id.

remember

Ako je istinito, također postavlja dugotrajni kolačić _remember. Proslijedite True za zadanih 30 dana, ili cijeli broj za broj dana koliko kolačić treba trajati.

redirect_url

Kamo preusmjeriti nakon prijave. Nadjačano s ?next=<url> iz izvornog zahtjeva ako pokazuje na putanju s istog mjesta (same-site).

Vraća odgovor preusmjeravanja – vratite njegovu vrijednost iz rukovatelja rute za prijavu.

async logout_user(request)

Briše korisnički ID iz sesije i uklanja sve kolačiće _remember. Koristite iz rute /logout

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

Vraća objekt trenutno prijavljenog korisnika (ili None). Memoiziran na request.g.current_user tako da ponovljeni pozivi unutar jednog zahtjeva pogađaju loader samo jednom.

Primjer

Minimalni tijek prijave:

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

Kolačić _remember sam je potpisani JWT (koristeći tajni ključ sesije), pa se ukradeni kolačić ne može ponovno upotrijebiti na drugoj aplikaciji ili nakon što je tajni ključ rotiran.