microdot.login — 사용자 로그인 흐름

microdot.session 을 감싸는 상위 수준 래퍼로, 일반적인 사용자 이름 / 비밀번호 로그인 흐름을 구현합니다. 사용자 로더 콜백이 세션에 저장된 사용자 ID를 애플리케이션의 사용자 객체로 다시 매핑하고, 라우트 데코레이터가 인증되지 않은 요청을 구성 가능한 로그인 URL로 리디렉션하며, 선택적인 “remember me” 쿠키를 통해 재방문자가 브라우저 세션을 넘어 로그인 상태를 유지할 수 있게 합니다.

로그인 객체가 생성되기 전에 애플리케이션에 microdot.session 이 초기화되어 있어야 합니다. 사용자 ID가 저장되는 곳이 바로 세션이기 때문입니다.

class Login

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

데코레이터가 인증되지 않은 요청을 리디렉션하는 URL. 애플리케이션은 이 라우트에 실제 로그인 폼/핸들러를 제공합니다. 기본값 '/login'.

user_loader(f)

사용자 확인 콜백을 등록하는 데코레이터입니다. f 는 세션에 저장된 사용자 ID를 받아 사용자 객체를 반환합니다(또는 ID가 더 이상 유효하지 않은 경우 – 삭제된 계정, 취소된 세션 등 – None).

login = Login()

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

라우트를 Login 인스턴스로 데코레이팅하면 인증 뒤에서 접근이 제어됩니다:

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

인증되지 않은 요청은 ?next=<original-url> 쿼리 매개변수와 함께 login_url 로 리디렉션되어, 로그인 핸들러가 사용자를 원래 있던 곳으로 다시 보낼 수 있습니다.

fresh(f)

__call__() 과 비슷하지만, “remember me” 쿠키로 복원된 세션은 거부합니다. 사용자는 마지막 전체 로그인 이후 명시적으로 로그인했어야 합니다. 도난당한 remember-me 쿠키가 접근하지 못하도록 민감한 라우트(비밀번호 변경, 계정 삭제)를 제어하는 데 사용됩니다.

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

request 에 대해 user 를 로그인 상태로 표시합니다. 사용자 ID를 세션에 저장하고 리디렉션 응답을 반환합니다.

user

사용자 로더가 반환한 사용자 객체. id 속성을 가지고 있어야 합니다.

remember

참인 값이면 수명이 긴 _remember 쿠키도 설정합니다. 기본 30일을 위해서는 True 를, 쿠키 유효 일수를 지정하려면 정수를 전달하십시오.

redirect_url

로그인 후 리디렉션할 위치. 원래 요청의 ?next=<url> 이 동일 사이트 경로를 가리키는 경우 그것으로 재정의됩니다.

리디렉션 응답을 반환합니다. 로그인 라우트 핸들러에서 그 값을 반환하십시오.

async logout_user(request)

세션에서 사용자 ID를 지우고 _remember 쿠키를 제거합니다. /logout 라우트에서 사용하십시오:

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

현재 로그인된 사용자 객체(또는 None)를 반환합니다. request.g.current_user 에 메모이즈되어, 한 요청 내에서 반복 호출해도 로더는 한 번만 호출됩니다.

예시

최소한의 로그인 흐름:

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

_remember 쿠키 자체는 (세션의 시크릿을 사용하여) 서명된 JWT이므로, 도난당한 쿠키는 다른 애플리케이션에서 또는 시크릿이 교체된 이후에는 재사용할 수 없습니다.