Självstudie: Lägga till inloggning i en Python Flask-webbapp
Den här självstudien är den tredje delen i en självstudieserie som visar hur du skapar en Python Flask-webbapp från grunden och integrerar autentisering med microsofts identitetsplattform. I den här handledningen lägger du till kod för att autentisera användare i den app du byggde.
- Importera nödvändiga moduler och konfigurationer
- Skapa en instans av en Flask-webbapp
- Konfigurera ProxyFix-mellanprogram för lokal utveckling
- Lägga till kod för att logga in och logga ut användare
- Definiera en startpunkt för webbappen
Importera nödvändiga paket och konfigurationer
Webbappen som du skapar använder det identity.web
paket som bygger på MSAL Python för att autentisera användare i webbappar. Om du vill importera identity.web
-paketet, Flask-ramverket, Flask-modulerna, Flask-sessionen och appkonfigurationerna som definierades i föregående självstudie lägger du till följande kod i 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
I det här kodfragmentet importerar du funktionerna redirect
, render_template
, request
, session
och url_for
: funktioner och objekt för hantering av webbbegäranden och sessioner i Flask. Du importerar också app_config
, som innehåller konfigurationsinställningarna för din app.
Skapa en instans av Flask-webbappen
När du har importerat de moduler som krävs initierar vi webbappen med hjälp av konfigurationerna i app-config
. Om du vill skapa en instans av webbappen lägger du till följande kodfragment i app.py
:
app = Flask(__name__)
app.config.from_object(app_config)
assert app.config["REDIRECT_PATH"] != "/", "REDIRECT_PATH must not be /"
Session(app)
I kodfragmentet ovan initierar du ett nytt Flask-program och läser in konfigurationsinställningarna med hjälp av app.config.from_object(app_config)
. Med hjälp av from_object
ärver appen konfigurationerna från den som anges i (app_config)
.
Du utför också en kontroll av påståenden för att säkerställa att omdirigeringssökvägen för din app inte är inställd på rotsökvägen ("/").
Session(app)
initierar sessionshantering för din app, vilket gör att du kan hantera sessioner och lagra data, till exempel användarautentiseringstillstånd för flera begäranden.
Konfigurera ProxyFix-mellanprogram för lokal utveckling
Eftersom exempelwebbappen körs på den lokala värden använder vi ProxyFix
middleware för att åtgärda URL-schemat och värdinformationen i begäranderubrikerna. Lägg till följande kod i app.py
för att tillämpa ProxyFix:
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
Initiera ett autentiseringsobjekt
Sedan initierar du ett autentiseringsobjekt genom att skapa en instans av klassen identity.web.Auth
. Du skickar också parametrarna session
, authority
, client_id
och client_credential
i konstruktorn när du initierar Auth-objektet enligt följande:
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"],
)
I det här kodfragmentet lägger app.jinja_env.globals.update(Auth=identity.web.Auth)
till en ny global variabel med namnet Auth
och tilldelar den värdet för identity.web.Auth
. Detta gör Auth
tillgängliga i alla mallar som återges av Flask-programmet.
Logga in användare
Auktoriseringsflödet som du skapar i den här appen består av två ben. I den första delen anropar du funktionen auth.log_in
för att logga in användare, enligt följande:
@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.
))
När en användare navigerar till /login
-URL:en i din app anropar Flask vyfunktionen som hanterar begäran om att återge login.html
mallen. I login()
anropar du funktionen auth.log_in
med en lista över omfång som användaren bör samtycka till under inloggningsprocessen. Du anger också redirect_uri
i parametrarna, som ska matcha appens omdirigerings-URI i administrationscentret för Microsoft Azure.
Du kan också lägga till parametrar som prompt
, som styr beteendet för inloggningsprompten genom att begära omautentisering, användarmedgivande eller kontoval mellan konton med aktiva sessioner.
I den andra delen av auktoriseringsflödet hanterar du autentiseringssvaret genom att anropa funktionen auth.complete_log_in
inuti den redirect_uri styrenheten enligt följande:
@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"))
Funktionen complete_log_in()
tar i den inkommande auth_response
ordlistan som frågeparametrar. Om det lyckas omdirigerar funktionen användaren till "index"-vägen med hjälp av redirect(url_for("index"))
. Det innebär att användaren har loggat in och att deras information är tillgänglig som en ordlista som innehåller anspråk från en redan verifierad ID-token.
Om resultatet innehåller ett fel som bestäms av villkoret if "error" in result:
återger du "auth_error.html"
mallen till användaren.
Logga ut användare
Om du vill logga ut användare från flaskprogrammet anropar du metoden auth.log_out()
enligt följande:
@app.route("/logout")
def logout():
return redirect(auth.log_out(url_for("index", _external=True)))
När en användare navigerar till /logout
URL-vägen i appen anropar Flask utloggningsfunktionen som loggar ut dem från den aktuella appen. Du anger också den sida som användarna ska omdirigeras till när de loggar ut. I kodfragmentet omdirigerar vi användare till appens startsida med hjälp av url_for("index", _external=True).
Definiera en startpunkt för webbappen
När du har implementerat inloggnings- och utloggningslogik lägger du till en startpunkt på appens startsida genom att skapa funktionen index()
på följande sätt:
@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__)
Funktionen index()
anropas när en användare navigerar till appens rot-URL("/"). Den hanterar konfigurationskontroller och validerar användarautentisering innan appens startsida återges. Den kontrollerar om klient-ID och klienthemlighet saknas i konfigurationen, och om något av eller båda värdena saknas renderar Flask "config_error.html"
mallen.
Funktionen anropar också auth.get_user()
för att kontrollera om användaren är autentiserad eller inte. Om användaren inte autentiseras omdirigeras de till "login"
vägen. Om den autentiseras renderar Flask mallen "index.html" och skickar användarobjektet (hämtat från auth.get_user()
) för återgivning.