Udostępnij za pośrednictwem


Samouczek: dodawanie logowania do aplikacji internetowej platformy Python Flask

Ten samouczek jest trzecią częścią serii samouczków, która demonstruje tworzenie aplikacji internetowej platformy Python Flask od podstaw i integrowanie uwierzytelniania przy użyciu platformy tożsamości firmy Microsoft. W tym samouczku dodasz kod w celu uwierzytelnienia użytkowników w utworzonej aplikacji.

  • Importowanie wymaganych modułów i konfiguracji
  • Utwórz aplikację webową na Flasku
  • Konfigurowanie oprogramowania pośredniczącego ProxyFix na potrzeby programowania lokalnego
  • Dodawanie kodu w celu zalogowania się i wylogowania użytkowników
  • Definiowanie punktu wejścia dla aplikacji internetowej

Importowanie wymaganych pakietów i konfiguracji

Tworzona aplikacja internetowa korzysta z pakietu identity.web utworzonego na podstawie biblioteki MSAL Python do uwierzytelniania użytkowników w aplikacjach internetowych. Aby zaimportować pakiet identity.web, platformę Flask, moduły platformy Flask, sesję platformy Flask i konfiguracje aplikacji zdefiniowane w poprzednim samouczku, dodaj następujący kod do 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

W tym fragmencie kodu zaimportujesz redirect, render_template, request, sessioni url_for: funkcje i obiekty do obsługi żądań internetowych i sesji na platformie Flask. Zaimportujesz również app_config, która zawiera ustawienia konfiguracji aplikacji.

Utwórz wystąpienie aplikacji webowej Flask

Po zaimportowaniu wymaganych modułów zainicjujemy aplikację internetową przy użyciu konfiguracji w app-config. Aby utworzyć wystąpienie aplikacji internetowej, dodaj następujący fragment kodu do app.py:

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

W powyższym fragmencie kodu zainicjujesz nową aplikację platformy Flask i załadujesz ustawienia konfiguracji przy użyciu app.config.from_object(app_config). Używając from_object, aplikacja dziedziczy konfiguracje określone w (app_config).

Wykonujesz również kontrolę asercji, aby upewnić się, że ścieżka przekierowania aplikacji nie jest ustawiona na ścieżkę główną ("/"). Session(app) inicjuje zarządzanie sesjami dla aplikacji, co umożliwia obsługę sesji i przechowywanie danych, takich jak stany uwierzytelniania użytkowników w wielu żądaniach.

Konfigurowanie oprogramowania pośredniczącego ProxyFix na potrzeby programowania lokalnego

Ponieważ przykładowa aplikacja internetowa działa na hoście lokalnym, używamy oprogramowania pośredniczącego ProxyFix, aby naprawić schemat adresów URL i informacje o hoście w nagłówkach żądania. Dodaj następujący kod do app.py, aby zastosować poprawkę serwera proxy:

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

Inicjowanie obiektu uwierzytelniania

Następnie zainicjujesz obiekt uwierzytelniania, tworząc wystąpienie klasy identity.web.Auth. Parametry session, authority, client_idi client_credential można również przekazać w konstruktorze przy inicjowaniu obiektu Auth w następujący sposób:

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

W tym fragmencie kodu app.jinja_env.globals.update(Auth=identity.web.Auth)dodaje nową zmienną globalną o nazwie Auth i przypisuje jej wartość identity.web.Auth. Dzięki temu Authjest dostępne we wszystkich szablonach renderowanych przez aplikację Flask.

Logowanie użytkowników

Przepływ autoryzacji, który tworzysz w tej aplikacji, składa się z dwóch etapów. W pierwszym etapie wywołujesz funkcję auth.log_in, aby logować użytkowników, jak pokazano poniżej:

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

Gdy użytkownik przejdzie do adresu URL /login w aplikacji, platforma Flask wywołuje funkcję widoku, która obsługuje żądanie renderowania szablonu login.html. Wewnątrz login()wywołasz funkcję auth.log_in z listą zakresów, na które użytkownik powinien wyrazić zgodę podczas procesu logowania. Podaj również redirect_uri w parametrach, które powinny być zgodne z identyfikatorem URI przekierowania aplikacji i centrum administracyjnym platformy Microsoft Azure.

Opcjonalnie możesz dodać parametry, takie jak prompt, które sterują zachowaniem monitu logowania, żądając ponownego uwierzytelnienia, zgody użytkownika lub wyboru konta między kontami z aktywnymi sesjami.

W drugiej części przepływu autoryzacji obsługiwana jest odpowiedź uwierzytelniania przez wywołanie funkcji auth.complete_log_in wewnątrz kontrolera redirect_uri, jak pokazano poniżej:

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

Funkcja complete_log_in() przyjmuje przychodzący słownik auth_response jako parametry zapytania. Jeśli operacja powiedzie się, funkcja przekierowuje użytkownika do trasy "index" przy użyciu redirect(url_for("index")). Oznacza to, że użytkownik pomyślnie się zalogował, a jego informacje są dostępne jako słownik zawierający roszczenia z już zweryfikowanego tokenu identyfikacyjnego.

Jeśli wynik zawiera błąd określony przez warunek if "error" in result:, wyświetl szablon "auth_error.html" użytkownikowi.

Wylogowywanie użytkowników

Aby wylogować użytkowników z aplikacji platformy Flask, wywołaj metodę auth.log_out() w następujący sposób:

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

Gdy użytkownik przejdzie do trasy adresu URL /logout w aplikacji, platforma Flask wywołuje funkcję wylogowywania, która wyloguje je z bieżącej aplikacji. Należy również określić stronę, do której użytkownicy powinni zostać przekierowani po wylogowaniu. W fragmencie kodu przekierowujemy użytkowników do strony głównej aplikacji przy użyciu url_for("index", _external=True).

Definiowanie punktu wejścia dla aplikacji internetowej

Po zaimplementowaniu logiki logowania i wylogowania dodaj punkt wejścia do strony głównej aplikacji, tworząc funkcję index() w następujący sposób:

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

Funkcja index() jest wywoływana, gdy użytkownik przechodzi do głównego adresu URL("/"). Obsługuje kontrole konfiguracji i weryfikuje uwierzytelnianie użytkownika przed renderowaniem strony głównej aplikacji. Sprawdza, czy w konfiguracji brakuje identyfikatora klienta i klucza tajnego klienta, a jeśli brakuje wartości lub obu tych wartości, platforma Flask renderuje szablon "config_error.html".

Funkcja wywołuje również auth.get_user() w celu sprawdzenia, czy użytkownik jest uwierzytelniony, czy nie. Jeśli użytkownik nie jest uwierzytelniony, przekierowuje go do trasy "login". W przypadku uwierzytelnienia platforma Flask renderuje szablon "index.html" i przekazuje obiekt użytkownika (pobrany z auth.get_user()) na potrzeby renderowania.

Następne kroki