microdot.login — fluxo de autenticação de utilizadores¶
Um invólucro de nível superior em torno de microdot.session que implementa o fluxo convencional de autenticação por nome de utilizador/palavra-passe: uma callback user loader mapeia o identificador de utilizador armazenado na sessão de volta ao objeto de utilizador da aplicação, os decoradores de rotas redirecionam pedidos não autenticados para um URL de autenticação configurável, e cookies opcionais de «lembrar-me» permitem que visitantes recorrentes permaneçam autenticados entre sessões do navegador.
Requer que microdot.session esteja inicializado na aplicação antes de o objeto de autenticação ser construído — a sessão é onde o identificador de utilizador é armazenado.
class Login¶
- class microdot.login.Login(login_url: str = '/login')¶
- login_url
URL para o qual o decorador redireciona pedidos não autenticados. A aplicação disponibiliza o formulário/handler de autenticação real nesta rota. Predefinição:
'/login'.
- user_loader(f)¶
Decorador que regista a callback de resolução de utilizador. f recebe o identificador de utilizador armazenado na sessão e devolve o objeto de utilizador (ou
Nonese o identificador já não for válido — conta eliminada, sessão revogada, etc.).login = Login() @login.user_loader async def load_user(user_id): return users.get(user_id)
- __call__(f)¶
Decorar uma rota com a instância
Loginprotege-a com autenticação:@app.get('/dashboard') @login async def dashboard(request): user = request.g.current_user # ...
Os pedidos não autenticados são redirecionados para login_url com um parâmetro de consulta
?next=<original-url>para que o handler de autenticação possa enviar o utilizador de volta ao ponto de origem.
- fresh(f)¶
Semelhante a
__call__(), mas rejeita sessões restauradas a partir de um cookie de «lembrar-me» — o utilizador deve ter iniciado sessão explicitamente desde o último login completo. Utilizado para proteger rotas sensíveis (alteração de palavra-passe, eliminação de conta) para que um cookie de lembrar-me roubado não consiga aceder a elas.
- async login_user(request, user, remember: bool | int = False, redirect_url: str = '/')¶
Marca user como autenticado para request. Armazena o identificador de utilizador na sessão e devolve uma resposta de redirecionamento.
- user
O objeto de utilizador devolvido pelo user loader. Deve ter um atributo
id.- remember
Se verdadeiro, define também um cookie
_rememberde longa duração. PasseTruepara o valor predefinido de 30 dias, ou um inteiro para o número de dias durante os quais o cookie deve ser válido.- redirect_url
Para onde redirecionar após a autenticação. Substituído por
?next=<url>do pedido original se apontar para um caminho do mesmo site.
Devolve a resposta de redirecionamento — devolva o seu valor a partir do handler da rota de autenticação.
- async logout_user(request)¶
Remove o identificador de utilizador da sessão e elimina qualquer cookie
_remember. Utilize numa rota/logout@app.post('/logout') async def logout(request): await login.logout_user(request) return redirect('/')
- async get_current_user(request)¶
Devolve o objeto de utilizador autenticado atualmente (ou
None). Memorizado emrequest.g.current_userpara que chamadas repetidas dentro de um pedido acedam ao loader apenas uma vez.
Exemplo¶
Um fluxo de autenticação mínimo:
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('/')
O cookie _remember é ele próprio um JWT assinado (utilizando o segredo da sessão), pelo que um cookie roubado não pode ser reutilizado noutra aplicação nem após a rotação do segredo.