Partilhar via


Tutorial: Adicionar login 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 a partir do zero e a integração da autenticação usando a plataforma de identidade da Microsoft. Neste tutorial, você adiciona código para autenticar usuários no aplicativo que você criou.

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

Importar pacotes e configurações necessários

O aplicativo Web que você está criando usa o pacote construído sobre o identity.web MSAL Python para autenticar usuários em aplicativos Web. Para importar o pacote, a estrutura do Flask, os identity.web módulos do Flask, a sessão do Flask e as configurações do 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 trecho de código, você importa as redirectfunções , render_template, request, session, e url_for: e objetos para lidar com solicitações da Web e sessões no Flask. Você também importa app_configo , que contém as definições de configuração para seu 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 seu aplicativo Web, adicione o seguinte trecho ao app.py:

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

No trecho de código acima, você inicializa um novo aplicativo Flask e carrega as definições de configuração usando app.config.from_object(app_config). from_objectUsando o , o aplicativo herda as configurações especificadas no (app_config).

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

Configurar middleware ProxyFix para desenvolvimento local

Como o aplicativo Web de exemplo é executado em host local, usamos o ProxyFix middleware para corrigir o esquema de URL e as informações do host nos cabeçalhos de solicitação. Adicione o seguinte código para app.py aplicar 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, inicialize um objeto de autenticação criando uma instância da [identity.web.Auth](https://identity-library.readthedocs.io/en/latest/#identity.web.Auth) classe. 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 trecho de código, app.jinja_env.globals.update(Auth=identity.web.Auth)adiciona uma nova variável global chamada Auth e atribui-lhe o valor de identity.web.Auth. Isso torna Authacessível em todos os modelos renderizados pelo aplicativo Flask.

Iniciar sessão de utilizadores

O fluxo de autorização que você cria neste aplicativo consiste em duas pernas. Na primeira etapa, você invoca a auth.log_in função para entrar nos 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 para a /login URL em seu aplicativo, o Flask invoca a função de exibição que lida com a solicitação para renderizar o login.html modelo. Dentro login()do , você chama a auth.log_in função com uma lista de escopos que o usuário deve consentir durante o processo de login. Você também fornece redirect_uri nos parâmetros, 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 login 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 auth.complete_log_in função 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 complete_log_in() função recebe o dicionário de entrada auth_response como os parâmetros de consulta. Se bem-sucedida, a função redireciona o usuário para a rota "index" usando redirect(url_for("index")). Isso significa que o usuário fez login 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 "auth_error.html" modelo para o usuário.

Sair de usuários

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

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

Quando um usuário navega para a /logout rota de URL no aplicativo, o Flask invoca a função de logout que o desconecta do aplicativo atual. Você também especifica a página para a qual os usuários devem ser redirecionados ao fazer logout. No trecho de código, redirecionamos os usuários para a página inicial 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 à página inicial do seu aplicativo criando a index() função 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 index() função é invocada quando um usuário navega até a URL raiz do aplicativo("/"). Ele lida com verificações de configuração e valida a autenticação do usuário antes de renderizar a página inicial do aplicativo. Ele verifica se o ID do cliente e o segredo do cliente estão faltando na configuração e, se um ou ambos os valores estiverem faltando, o Flask renderiza o "config_error.html" modelo.

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, ele o redirecionará para a "login" rota. Se autenticado, o Flask renderiza o modelo "index.html" e passa o objeto de usuário (recuperado de auth.get_user()) para renderização.

Próximos passos