microdot.login — fluxo de login de usuário¶
Um wrapper de mais alto nível em torno de microdot.session que implementa o fluxo convencional de login com nome de usuário / senha: um callback carregador de usuário mapeia o user-id armazenado na sessão de volta para o objeto de usuário da aplicação, decoradores de rota redirecionam requisições não autenticadas para uma URL de login configurável, e cookies opcionais de “lembrar de mim” permitem que visitantes recorrentes permaneçam conectados entre sessões do navegador.
Requer que microdot.session esteja inicializado na aplicação antes de o objeto de login ser construído – a sessão é onde o user-id é armazenado.
class Login¶
- class microdot.login.Login(login_url: str = '/login')¶
- login_url
URL para a qual o decorador redireciona requisições não autenticadas. A aplicação fornece o formulário/manipulador de login real nesta rota. Padrão
'/login'.
- user_loader(f)¶
Decorador que registra o callback de resolução de usuário. f recebe o user-id armazenado na sessão e retorna o objeto de usuário (ou
Nonese o id não for mais válido – uma conta excluída, uma 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 de
Logina protege por trás da autenticação:@app.get('/dashboard') @login async def dashboard(request): user = request.g.current_user # ...
Requisições não autenticadas são redirecionadas para login_url com um parâmetro de consulta
?next=<original-url>para que o manipulador de login possa enviar o usuário de volta para onde estava.
- fresh(f)¶
Como
__call__(), mas rejeita sessões restauradas a partir de um cookie de “lembrar de mim” – o usuário deve ter feito login explicitamente desde o último login completo. Usado para proteger rotas sensíveis (alteração de senha, exclusão de conta) de modo que um cookie de lembrar-de-mim roubado não consiga alcançá-las.
- async login_user(request, user, remember: bool | int = False, redirect_url: str = '/')¶
Marca user como conectado para request. Armazena o id do usuário na sessão e retorna uma resposta de redirecionamento.
- user
O objeto de usuário retornado pelo carregador de usuário. Deve ter um atributo
id.- remember
Se verdadeiro, também define um cookie
_rememberde longa duração. PasseTruepara os 30 dias padrão, ou um inteiro para o número de dias que o cookie deve durar.- redirect_url
Para onde redirecionar após o login. Sobrescrito por
?next=<url>da requisição original se apontar para um caminho do mesmo site.
Retorna a resposta de redirecionamento – retorne seu valor a partir do manipulador da rota de login.
- async logout_user(request)¶
Limpa o id do usuário da sessão e remove qualquer cookie
_remember. Use a partir de uma rota/logout@app.post('/logout') async def logout(request): await login.logout_user(request) return redirect('/')
- async get_current_user(request)¶
Retorna o objeto do usuário atualmente conectado (ou
None). Memorizado emrequest.g.current_userpara que chamadas repetidas dentro de uma requisição acessem o carregador apenas uma vez.
Exemplo¶
Um fluxo de login 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 (usando o segredo da sessão), de modo que um cookie roubado não pode ser reutilizado em uma aplicação diferente ou após o segredo ter sido rotacionado.