microdot.login — przepływ logowania użytkownika

Wyższego poziomu nakładka na microdot.session, która implementuje konwencjonalny przepływ logowania za pomocą nazwy użytkownika / hasła: wywołanie zwrotne user loader mapuje przechowywany w sesji identyfikator użytkownika z powrotem na obiekt użytkownika aplikacji, dekoratory tras przekierowują nieuwierzytelnione żądania na konfigurowalny adres URL logowania, a opcjonalne pliki cookie „zapamiętaj mnie” pozwalają powracającym odwiedzającym pozostać zalogowanymi między sesjami przeglądarki.

Wymaga zainicjowania microdot.session w aplikacji przed skonstruowaniem obiektu logowania – sesja jest miejscem, w którym przechowywany jest identyfikator użytkownika.

class Login

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

Adres URL, na który dekorator przekierowuje nieuwierzytelnione żądania. Aplikacja udostępnia właściwy formularz/procedurę obsługi logowania na tej trasie. Domyślnie '/login'.

user_loader(f)

Dekorator rejestrujący wywołanie zwrotne rozpoznające użytkownika. f przyjmuje identyfikator użytkownika przechowywany w sesji i zwraca obiekt użytkownika (lub None, jeśli identyfikator nie jest już prawidłowy – usunięte konto, unieważniona sesja itp.).

login = Login()

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

Udekorowanie trasy instancją Login chroni ją za uwierzytelnianiem:

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

Nieuwierzytelnione żądania są przekierowywane na login_url z parametrem zapytania ?next=<original-url>, aby procedura obsługi logowania mogła odesłać użytkownika tam, skąd przyszedł.

fresh(f)

Podobnie jak __call__(), ale odrzuca sesje przywrócone z pliku cookie „zapamiętaj mnie” – użytkownik musiał zalogować się jawnie od ostatniego pełnego logowania. Używane do ochrony wrażliwych tras (zmiana hasła, usunięcie konta), aby skradziony plik cookie zapamiętania nie mógł do nich dotrzeć.

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

Oznacza użytkownika user jako zalogowanego dla request. Przechowuje identyfikator użytkownika w sesji i zwraca odpowiedź przekierowania.

user

Obiekt użytkownika zwrócony przez user loader. Musi mieć atrybut id.

remember

Jeśli prawdziwe, ustawia również długotrwały plik cookie _remember. Przekaż True dla domyślnych 30 dni lub liczbę całkowitą określającą liczbę dni, przez które plik cookie ma obowiązywać.

redirect_url

Dokąd przekierować po zalogowaniu. Nadpisywane przez ?next=<url> z pierwotnego żądania, jeśli wskazuje na ścieżkę z tej samej witryny.

Zwraca odpowiedź przekierowania – zwróć jej wartość z procedury obsługi trasy logowania.

async logout_user(request)

Usuwa identyfikator użytkownika z sesji i usuwa wszelkie pliki cookie _remember. Użyj z trasy /logout

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

Zwraca obiekt aktualnie zalogowanego użytkownika (lub None). Memoizowany w request.g.current_user, więc powtarzane wywołania w obrębie jednego żądania trafiają do loadera tylko raz.

Przykład

Minimalny przepływ logowania:

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

Plik cookie _remember sam jest podpisanym JWT (z użyciem sekretu sesji), więc skradziony plik cookie nie może zostać ponownie użyty w innej aplikacji ani po rotacji sekretu.