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
, session
i 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_id
i 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 Auth
jest 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.