Flask – Autenticação

Nesse post vou mostrar como fazer uma autenticação básica utilizando, Flask, Blueprints e Decorators, caso você ainda não saiba o que é isso eu tenho os links aqui:

Flask Basico – http://alissonmachado.com.br/flask-basico/
Blueprints – http://alissonmachado.com.br/flask-blueprints/
Decorators – http://alissonmachado.com.br/python-flask-decorators-e-pytest/

A ideia aqui é ser simples e rápido.

Então vamos lá =)

Vamos criar 3 arquivos:

app.py

from flask import Flask
from admin import admin
from auth import auth
 
app = Flask(__name__)
app.register_blueprint(admin)
app.register_blueprint(auth)
 
app.secret_key = "senha_secreta"
 
@app.route("/")
def index():
    return "Pagina principal"
 
if __name__ == '__main__':
    app.run(debug=True)

auth.py

import functools
 
from flask import Blueprint, redirect, request, session
 
 
auth = Blueprint("auth",__name__)
 
def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):        
        if not 'nome' in session.keys():
            return redirect("/login")
        return view(**kwargs)
    return wrapped_view
 
@auth.route('/login',)
def login():
    try:
        username = request.args['username']
        password = request.args['password']
    except Exception as e:
        print(e)
        return "Passe o username e o password na query string ex: ?username=alisson&password=12345"
    if username != 'alisson' and password != '12345':
        return 'Incorrect username.'                    
 
    session['nome'] = username
    return "usuario logado: %s"%session['nome']
 
@auth.route('/logout')
def logout():
    session.clear()
    return "deslogado"

admin.py

from flask import Blueprint
from auth import login_required
 
admin = Blueprint("admin",__name__)
 
@admin.route("/admin")
@login_required
def painel():
    return "Tela de admin"

Agora explicando como funciona.

No app.py basicamente temos a index do nosso sistema e o secret_key que serve para criptografar os cookies que são utilizados na sessão enquanto o usuário estiver logado.

No admin.py temos o import da função login_required que está declarada no auth.py, essa função é um decorator, pois ela retorna uma outra função no final da sua execução.

Então como isso funciona? Quando é feita uma request em /admin, o decorator valida se existe um login ativo, se existir ele retorna a função que foi chamada, no nosso caso a tela de admin, caso contrário ele retorna uma outra função, que seria encaminhar para a tela de login.

Agora estudando o auth.py

Dos 3 arquivos esse é o relativamente mais complexo, pois no trecho abaixo temos a parte que faz a validação do usuário logado:

def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):        
        if not 'nome' in session.keys():
            return redirect("/login")
        return view(**kwargs)
    return wrapped_view

Como ele funciona? No flask temos esse objeto session que foi importado, ele é um dicionário, então para saber se temos alguém logado é necessario verificar se existe a chave ‘nome’ criada dentro dele, se ela existir, é retornada a função original, a tela de admin, caso contrário ele faz um redirect para /login, forçando assim a autenticação desse usuário.

Na página de login temos esse código:

@auth.route('/login',)
def login():
    try:
        username = request.args['username']
        password = request.args['password']
    except Exception as e:
        print(e)
        return "Passe o username e o password na query string ex: ?username=alisson&password=12345"
    if username != 'alisson' and password != '12345':
        return 'Incorrect username.'                    
 
    session['nome'] = username
    return "usuario logado: %s"%session['nome']

Esse código pega os parametros username e password via query string, caso esses sejam iguais a alisson e 12345, ele cria uma sessão ‘nome’ armazenando o username do usuário que está acessando o sistema.

Para fazer o logout é basicamente uma linha que limpa a sessão, segue o código abaixo:

@auth.route('/logout')
def logout():
    session.clear()
    return "deslogado"

é isso ae, flws.