microdot.login --- ユーザーログインフロー¶
従来のユーザー名/パスワードによるログインフローを実装する、microdot.session 上位のラッパーです。user loader コールバックがセッションに格納されたユーザー 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にメモ化されるため、1 つのリクエスト内で繰り返し呼び出してもローダーは一度しか実行されません。
例¶
最小限のログインフロー:
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 であるため、盗まれたクッキーを別のアプリケーションで、またはシークレットがローテーションされた後で再利用することはできません。