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.