Compartilhar via


Tutorial: Adicionar entrada a um aplicativo Web Python Flask

Este tutorial é a terceira parte de uma série de tutoriais que demonstra a criação de um aplicativo Web Python Flask do zero e a integração da autenticação usando a plataforma de identidade da Microsoft. Neste tutorial, você adicionará o código para autenticar usuários no aplicativo criado.

  • Importar os módulos e a configuração exigidos
  • Criar uma instância de um aplicativo Web Flask
  • Configurar o middleware ProxyFix para desenvolvimento local
  • Adicionar código para entrada e saída de usuários
  • Definir um ponto de entrada para o aplicativo Web

Importar os pacotes e as configurações necessários

O aplicativo Web que você está criando usa o pacote identity.web criado sobre a MSAL Python para autenticar usuários em aplicativos Web. Para importar o pacote identity.web, a estrutura, os módulos e a sessão do Flask, bem como as configurações de aplicativo definidas no tutorial anterior, adicione o seguinte código ao app.py:

import identity.web
import requests
from flask import Flask, redirect, render_template, request, session, url_for
from flask_session import Session

import app_config

Neste snippet de código, você importa as funções redirect, render_template, request, session e url_for: funções e objetos para lidar com solicitações e sessões da Web no Flask. Você também importa app_config, que contém as configurações do aplicativo.

Criar uma instância do aplicativo Web Flask

Depois de importar os módulos necessários, inicializamos o aplicativo Web usando as configurações em app-config. Para criar uma instância do aplicativo Web, adicione o seguinte snippet a app.py:

app = Flask(__name__)
app.config.from_object(app_config)
assert app.config["REDIRECT_PATH"] != "/", "REDIRECT_PATH must not be /"
Session(app)

No snippet de código acima, você inicializa um novo aplicativo Flask e carrega as configurações usando app.config.from_object(app_config). Ao usar from_object, o aplicativo herda as configurações do especificado em (app_config).

Você também executa uma verificação de declaração para garantir que o caminho de redirecionamento do aplicativo não esteja definido como o caminho raiz ("/"). O Session(app) inicializa o gerenciamento de sessão para seu aplicativo, o que permite que você manipule sessões e armazene dados, como estados de autenticação de usuário, em várias solicitações.

Configurar o middleware ProxyFix para desenvolvimento local

Como o aplicativo Web de exemplo é executado no host local, usamos o middleware ProxyFix para corrigir o esquema de URL e as informações de host nos cabeçalhos da solicitação. Adicione o seguinte código a app.py para aplicar o ProxyFix:

from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

Inicializar um objeto de autenticação

Em seguida, você inicializa um objeto de autenticação criando uma instância da classe [identity.web.Auth](https://identity-library.readthedocs.io/en/latest/#identity.web.Auth). Você também passa os parâmetros session, authority, client_id e client_credential no construtor ao inicializar o objeto Auth, da seguinte maneira:

app.jinja_env.globals.update(Auth=identity.web.Auth)  # Useful in template for B2C
auth = identity.web.Auth(
    session=session,
    authority=app.config["AUTHORITY"],
    client_id=app.config["CLIENT_ID"],
    client_credential=app.config["CLIENT_SECRET"],
)

Neste snippet de código, app.jinja_env.globals.update(Auth=identity.web.Auth) adiciona uma nova variável global chamada Auth e atribui a ela o valor de identity.web.Auth. Isso torna Auth acessível em todos os modelos renderizados pelo aplicativo Flask.

Conectar usuários

O fluxo de autorização que você constrói neste aplicativo consiste em duas ramificações. Na primeira ramificação, você invoca a função auth.log_in para conectar usuários, conforme mostrado:

@app.route("/login")
def login():
    return render_template("login.html", version=__version__, **auth.log_in(
        scopes=app_config.SCOPE, # Have user consent to scopes during log-in
        redirect_uri=url_for("auth_response", _external=True), # Optional. If present, this absolute URL must match your app's redirect_uri registered in Microsoft Entra admin center
        prompt="select_account",  # Optional.
        ))

Quando um usuário navega até a URL /login em seu aplicativo, o Flask invoca a função de exibição que manipula a solicitação para renderizar o modelo login.html. Dentro de login(), você chama a função auth.log_in com uma lista de escopos aos quais o usuário deve consentir durante o processo de entrada. Você também fornece os parâmetros redirect_uri, que devem corresponder ao URI de redirecionamento do aplicativo no Centro de administração do Microsoft Azure.

Opcionalmente, você pode adicionar parâmetros como prompt, que controla o comportamento do prompt de logon solicitando reautenticação, consentimento do usuário ou seleção de conta entre contas com sessões ativas.

Na segunda etapa do fluxo de autorização, você manipula a resposta de autenticação chamando a função auth.complete_log_in dentro do controlador redirect_uri, conforme mostrado:

@app.route(app_config.REDIRECT_PATH)
def auth_response():
    result = auth.complete_log_in(request.args)
    if "error" in result:
        return render_template("auth_error.html", result=result)
    return redirect(url_for("index"))

A função complete_log_in() usa o dicionário auth_response de entrada como os parâmetros de consulta. Se tiver êxito, a função redirecionará o usuário para a rota "index" usando redirect(url_for("index")). Isto significa que o usuário fez logon com sucesso e suas informações estão disponíveis como um dicionário contendo declarações de um token de ID já validado.

Se o resultado contiver um erro conforme determinado pela condição if "error" in result:, renderize o modelo "auth_error.html" para o usuário.

Desconectar usuários

Para desconectar usuários do aplicativo Flask, invoque o método auth.log_out() da seguinte maneira:

@app.route("/logout")
def logout():
    return redirect(auth.log_out(url_for("index", _external=True)))

Quando um usuário navega até a rota da URL /logout no aplicativo, o Flask invoca a função de logoff que os desconecta do aplicativo atual. Você também especifica a página para a qual os usuários devem ser redirecionados ao fazer logoff. No snippet de código, redirecionamos os usuários para a home page do aplicativo usando url_for("index", _external=True).

Definir um ponto de entrada para o aplicativo Web

Depois de implementar a lógica de entrada e saída, adicione um ponto de entrada à home page do aplicativo criando a função index() da seguinte maneira:

@app.route("/")
def index():
    if not (app.config["CLIENT_ID"] and app.config["CLIENT_SECRET"]):
        # This check is not strictly necessary.
        # You can remove this check from your production code.
        return render_template('config_error.html')
    if not auth.get_user():
        return redirect(url_for("login"))
    return render_template('index.html', user=auth.get_user(), version=__version__)

A função index() é invocada quando um usuário navega para a URL raiz do aplicativo("/"). Ela manipula as verificações de configuração e valida a autenticação do usuário antes de renderizar a home page do aplicativo. Ela verifica se a ID do cliente e o segredo do cliente estão ausentes na configuração e, se um ou ambos os valores estiverem ausentes, o Flask renderiza o modelo "config_error.html".

A função também chama auth.get_user() para verificar se o usuário está autenticado ou não. Se o usuário não estiver autenticado, ela o redirecionará para a rota "login". Se estiver autenticado, o Flask renderiza o modelo "index.html" e passa o objeto de usuário (recuperado de auth.get_user()) para renderização.

Próximas etapas