Alisson Machado
21 May 2019

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.