Бөлісу құралы:


Руководство. Добавление входа в веб-приложение Python Flask

Это третье руководство серии учебников, демонстрирующее создание веб-приложения Python Flask с нуля и интеграцию проверки подлинности с помощью платформы удостоверений Майкрософт. В этом руководстве вы добавите код для проверки подлинности пользователей в созданном приложении.

  • Импорт необходимых модулей и конфигурации
  • Создание экземпляра веб-приложения Flask
  • Настройка ПО промежуточного слоя ProxyFix для локальной разработки
  • Добавление кода для входа и выхода пользователей
  • Определение точки входа для веб-приложения

Импорт обязательных пакетов и конфигураций

Веб-приложение, которое вы создаете, использует пакет identity.web, созданный на основе MSAL Python, для проверки подлинности пользователей в веб-приложениях. Чтобы импортировать пакет identity.web, платформу Flask, модули Flask, сеанс Flask и конфигурации приложений, определенные в предыдущем руководстве, добавьте следующий код в 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

В этом фрагменте кода импортируется redirect, render_template, request, sessionи url_for: функции и объекты для обработки веб-запросов и сеансов в Flask. Вы также импортируете app_config, которая содержит параметры конфигурации для приложения.

Создание экземпляра веб-приложения Flask

После импорта необходимых модулей мы инициализируем веб-приложение с помощью конфигураций в app-config. Чтобы создать экземпляр веб-приложения, добавьте следующий фрагмент кода в app.py:

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

В приведенном выше фрагменте кода вы инициализируете новое приложение Flask и загружаете параметры конфигурации с помощью app.config.from_object(app_config). С помощью from_objectприложение наследует конфигурации от указанного в (app_config).

Вы также выполняете проверку утверждения, чтобы убедиться, что путь перенаправления приложения не задан для корневого пути ("/"). Session(app) инициализирует управление сеансами для приложения, что позволяет обрабатывать сеансы и хранить такие данные, как состояния проверки подлинности пользователей в нескольких запросах.

Настройка ПО промежуточного слоя ProxyFix для локальной разработки

Так как пример веб-приложения выполняется на локальном узле, мы используем ПО промежуточного слоя ProxyFix для исправления схемы URL-адресов и сведений о узле в заголовках запроса. Добавьте следующий код в app.py для применения ProxyFix:

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

Инициализация объекта проверки подлинности

Затем вы инициализируете объект проверки подлинности, создав экземпляр класса identity.web.Auth. Вы также передаете параметры session, authority, client_idи client_credential в конструкторе при инициализации объекта Auth следующим образом:

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"],
)

В этом фрагменте кода app.jinja_env.globals.update(Auth=identity.web.Auth)добавляет новую глобальную переменную с именем Auth и присваивает ему значение identity.web.Auth. Это делает Authдоступным во всех шаблонах, отображаемых приложением Flask.

Вход пользователей

Поток авторизации, который вы создаете в этом приложении, состоит из двух этапов. На первом этапе вы вызываете функцию auth.log_in для входа пользователей, как показано ниже.

@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.
        ))

Когда пользователь переходит к URL-адресу /login в приложении, Flask вызывает функцию представления, которая обрабатывает запрос для отрисовки шаблона login.html. Внутри login()вызывается функция auth.log_in со списком областей, на которые пользователь должен предоставить согласие во время входа. Вы также предоставляете redirect_uri в параметрах, которые должны соответствовать URI перенаправления приложения в Центре администрирования Microsoft Azure.

При необходимости можно добавить такие параметры, как prompt, который управляет поведением запроса на вход, запрашивая повторную аутентификацию, согласие пользователя или выбор учетной записи среди аккаунтов с активными сеансами.

Во второй части потока авторизации вы обрабатываете ответ проверки подлинности, вызвав функцию auth.complete_log_in внутри контроллера redirect_uri, как показано ниже.

@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"))

Функция complete_log_in() принимает входящий словарь auth_response в качестве параметров запроса. При успешном выполнении функция перенаправляет пользователя на маршрут "index" с помощью redirect(url_for("index")). Это означает, что пользователь успешно вошел в систему, и его информация доступна в виде словаря, содержащего утверждения из уже проверенного ID токена.

Если результат содержит ошибку, определяемую условием if "error" in result:, то представьте пользователю шаблон "auth_error.html".

Выход пользователей

Чтобы выйти из приложения Flask, вызовите метод auth.log_out() следующим образом:

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

Когда пользователь переходит к маршруту /logout в URL приложения, Flask вызывает функцию выхода, которая выполняет выход из текущей сессии в приложении. Вы также указываете страницу, на которую следует перенаправить пользователей при выходе. В фрагменте кода мы перенаправляем пользователей на домашнюю страницу приложения с помощью url_for("index", _external=True).

Определение точки входа для веб-приложения

После реализации логики входа и выхода добавьте точку входа на домашнюю страницу приложения, создав функцию index() следующим образом:

@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__)

Функция index() вызывается при переходе пользователя к корневому URL-адресу приложения ("/"). Он обрабатывает проверки конфигурации и валидирует аутентификацию пользователей перед отображением главной страницы приложения. Он проверяет, отсутствует ли идентификатор клиента и секрет клиента в конфигурации, а если отсутствуют оба значения, Flask отрисовывает шаблон "config_error.html".

Функция также вызывает auth.get_user(), чтобы проверить, прошел ли пользователь проверку подлинности или нет. Если пользователь не прошел проверку подлинности, он перенаправляет их на маршрут "login". При проверке подлинности Flask отрисовывает шаблон "index.html" и передает объект пользователя (полученный из auth.get_user()) для отрисовки.

Дальнейшие действия

Руководство: Вызов защищенного API и отображение результатов в веб-приложении на Python Flask