So erstellen Sie eine SSO-Schaltfläche – Ein Flask-Login-Tutorial
Veröffentlicht: 2022-03-11Anwendungen benötigen häufig eine Anmeldefunktion, damit Benutzer Daten speichern, ihre eigenen Profile erstellen oder vielleicht nur den Zugriff auf sensible Ressourcen einschränken können. In einer modernen App erwarten Benutzer standardmäßige Anmeldefunktionen wie E-Mail-Bestätigung, Kennwortzurücksetzung oder Multi-Faktor-Authentifizierung. Diese Funktionen sind zwar notwendig, aber nicht einfach richtig hinzubekommen und normalerweise nicht das Hauptgeschäft der App.
Auf der Benutzerseite möchten sie möglicherweise auch nicht den langwierigen Registrierungsprozess durchlaufen, da sie ein weiteres E-Mail- und Passwort-Paar erstellen und sich merken müssen. Ohne einen geeigneten Passwort-Manager neigen Benutzer dazu, dasselbe Passwort wiederzuverwenden, was in Bezug auf die Sicherheit schrecklich ist.
Als Lösung für dieses Problem wurde Single Sign-On (SSO) erfunden, das den Benutzern meist als Anmeldung mit Social-Media- Schaltflächen bekannt ist. Für die Benutzer war es einfach, keinen weiteren schmerzhaften Registrierungsprozess zu durchlaufen. Für Unternehmen ist es immer ein großer Gewinn, Reibungsverluste für Benutzer zu beseitigen – und für Entwickler werden alle Login-bezogenen Funktionen jetzt an den Identitätsanbieter (Facebook, Google, Twitter usw.) delegiert , was weniger Code bedeutet! Ihre App vertraut einfach darauf, dass der Identitätsanbieter seine Aufgabe zur Überprüfung der Benutzeridentität erfüllt.
SSO wird normalerweise vom OpenId Connect (OIDC)- oder SAML-Protokoll unterstützt. SAML wird hauptsächlich in Unternehmensanwendungen verwendet. OIDC baut auf OAuth2 auf und wird von Anbietern sozialer Identitäten wie Facebook, Google usw. verwendet. In diesem Beitrag konzentrieren wir uns auf das OIDC/OAuth2-Protokoll.
In diesem Tutorial zur Flask-Anmeldung schreiben wir eine Schritt-für-Schritt-Anleitung zum Hinzufügen einer SSO-Anmeldeschaltfläche zu einer Flask-Anwendung mit SimpleLogin und Facebook als Identitätsanbieter. Dies kann ohne Verwendung einer externen Bibliothek erfolgen, aber um die Feinheiten von OAuth zu vereinfachen, verwenden wir Requests-OAuthlib, eine Bibliothek zur Integration von OAuth-Anbietern. Wenn Sie daran interessiert sind, SSO von Grund auf neu zu implementieren, lesen Sie bitte Implement SSO Login – the raw way .
Am Ende dieses Artikels sollten Sie eine Flask-App haben, die die folgenden Seiten hat:
- Homepage mit Login-Buttons
- Benutzerinformationsseite, auf der der Benutzer nach erfolgreicher Anmeldung Informationen wie Name, E-Mail und Avatar sehen kann
Den gesamten Code für dieses Tutorial finden Sie im Repository Flask-Social-Login-Example.
Eine Demo ist auch hier verfügbar. Fühlen Sie sich frei, den Code auf Glitch zu remixen.
Schritt 1: Bootstrap Flask-App
Flask und Requests-OAuthlib
flask
Sie können auch virtualenv
oder pipenv
, um die Umgebung zu isolieren.
pip install Flask-Requests_oauthlib
Erstellen Sie app.py
und die Route, die eine Anmeldeschaltfläche auf der Startseite anzeigt:
import flask app = flask.Flask(__name__) @app.route("/") def index(): return """ <a href="/login">Login</a> """ if __name__ == '__main__': app.run(debug=True)
Lassen Sie uns diese App ausführen und überprüfen, ob alles gut funktioniert:
python app.py
Sie sollten diese Seite sehen, wenn Sie http://localhost:5000 öffnen. Der vollständige Code befindet sich auf step1.py.
Schritt 2: Identitätsanbieter-Anmeldeinformationen
Derzeit gibt es Hunderte (wenn nicht Tausende) von Identitätsanbietern, wobei die beliebtesten Facebook, Google, GitHub und Instagram sind. Für diesen Beitrag wurde SimpleLogin aufgrund seiner Entwicklerfreundlichkeit ausgewählt. Derselbe Code funktioniert jedoch mit jedem OAuth2-Identitätsanbieter. (Haftungsausschluss: Ich bin zufällig der Mitbegründer von SimpleLogin, was – ähm – ein Faktor bei meiner Entscheidung gewesen sein könnte, es zu verwenden.)
Bitte gehen Sie zu SimpleLogin und erstellen Sie ein Konto, falls Sie noch keines haben, und erstellen Sie dann eine neue App auf der Registerkarte „Entwickler“.
Kopieren Sie bitte auf der App-Detailseite Ihre AppID und Ihr AppSecret und speichern Sie diese in der Variablenumgebung. In der OAuth-Terminologie bedeutet Client eigentlich eine Drittanbieter-App, dh Ihre App. Wir können diese Werte direkt in den Code einfügen, aber es empfiehlt sich, Anmeldeinformationen in Umgebungsvariablen zu speichern. Dies ist auch der dritte Faktor in den Zwölf Faktoren.
export CLIENT_ID={your AppID} export CLIENT_SECRET={your AppSecret}
Fügen Sie in app.py
diese Zeilen oben in die Datei ein, um die client id
und das client secret
zu erhalten.
import os CLIENT_ID = os.environ.get("CLIENT_ID") CLIENT_SECRET = os.environ.get("CLIENT_SECRET")
Bitte fügen Sie diese OAuth-URLs oben in app.py
, die im nächsten Schritt verwendet werden. Sie können auch auf der Seite OAuth-Endpunkte kopiert werden.
AUTHORIZATION_BASE_URL = "https://app.simplelogin.io/oauth2/authorize" TOKEN_URL = "https://app.simplelogin.io/oauth2/token" USERINFO_URL = "https://app.simplelogin.io/oauth2/userinfo"
Da wir uns jetzt keine Gedanken über die Einrichtung von SSL machen wollen, teilen wir Requests-OAuthlib
mit, dass es in Ordnung ist, einfaches HTTP zu verwenden:
# This allows us to use a plain HTTP callback os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
Wie üblich befindet sich der Code für diesen Schritt auf step2.py.
Schritt 3: Anmeldeumleitung
Wenn ein Benutzer auf die Anmeldeschaltfläche klickt:
- Der Benutzer wird auf die Autorisierungsseite des Identitäts-Login-Anbieters umgeleitet und gefragt, ob der Benutzer seine Informationen mit Ihrer App teilen möchte.
- Nach der Genehmigung durch den Benutzer werden sie zusammen mit einem
code
in der URL, die Ihre App verwendet, um sie gegen einaccess token
auszutauschen, das es Ihnen ermöglicht, später Benutzerinformationen vom Dienstanbieter zu erhalten, zu einer Seite Ihrer App zurückgeleitet.
Wir brauchen also zwei Routen: eine login
-Route, die den Benutzer zum Identitätsanbieter umleitet, und eine callback
-Route, die den code
und gegen den access token
austauscht. Die Rückrufroute ist auch für die Anzeige von Benutzerinformationen zuständig.

@app.route("/login") def login(): simplelogin = requests_oauthlib.OAuth2Session( CLIENT_ID, redirect_uri="http://localhost:5000/callback" ) authorization_url, _ = simplelogin.authorization_url(AUTHORIZATION_BASE_URL) return flask.redirect(authorization_url) @app.route("/callback") def callback(): simplelogin = requests_oauthlib.OAuth2Session(CLIENT_ID) simplelogin.fetch_token( TOKEN_URL, client_secret=CLIENT_SECRET, authorization_response=flask.request.url ) user_info = simplelogin.get(USERINFO_URL).json() return f""" User information: <br> Name: {user_info["name"]} <br> Email: {user_info["email"]} <br> Avatar <img src="{user_info.get('avatar_url')}"> <br> <a href="/">Home</a> """
Wenn Sie auf die Anmeldeschaltfläche klicken, sollten Sie durch den folgenden Ablauf geführt werden. Den vollständigen Code finden Sie auf GitHub unter step3.py.
Mit Facebook einloggen
Die Einrichtung der Facebook-, Google- und Twitter-Anmeldung ist etwas komplex und erfordert zusätzliche Schritte wie die Einrichtung von SSL oder die Auswahl der richtigen Bereiche. Diese gehen über den Rahmen dieses Artikels hinaus.
Abgesehen von einer ausgefeilten Benutzeroberfläche könnte der schwierigste Teil bei der Integration von Facebook darin bestehen, einen Weg zu finden, Ihre Webanwendung lokal auf HTTPS bereitzustellen, da die neue Version des Facebook-SDK kein lokales einfaches HTTP zulässt. Ich empfehle die Verwendung von Ngrok, einem kostenlosen Tool, um eine schnelle HTTPS-URL zu haben.
Schritt 1: Erstellen Sie eine Facebook-App
Bitte gehen Sie zu https://developers.facebook.com
und erstellen Sie eine neue App:
Wählen Sie dann auf dem nächsten Bildschirm „Facebook-Login integrieren“:
Schritt 2: Facebook-OAuth-Anmeldeinformationen
Klicken Sie links auf „Settings/Basic“ und kopieren Sie die App-ID und das App-Secret . Sie sind eigentlich OAuth client-id
und client-secret
.
Aktualisieren Sie die client-id
und client-secret
.
export FB_CLIENT_ID={your facebook AppId} export FB_CLIENT_SECRET={your facebook AppSecret}
Aktualisieren Sie die AUTHORIZATION_BASE_URL und TOKEN_URL:
FB_AUTHORIZATION_BASE_URL = "https://www.facebook.com/dialog/oauth" FB_TOKEN_URL = "https://graph.facebook.com/oauth/access_token"
Die Homepage:
@app.route("/") def index(): return """ <a href="/fb-login">Login with Facebook</a> """
Schritt 3: Anmelde- und Rückrufendpunkte
Wenn die App mit dem Befehl ngrok http 5000
hinter ngrok
bereitgestellt wird, müssen wir die aktuelle URL auf die ngrok-URL setzen.
# Your ngrok url, obtained after running "ngrok http 5000" URL = "https://abcdefgh.ngrok.io"
Bitte stellen Sie sicher, dass Sie die URL zu Ihrer Facebook-Anmeldung/Einstellungen, gültige OAuth-Umleitungs-URIs-Einstellung hinzufügen:
Um Zugriff auf eine Benutzer-E-Mail zu haben, müssen Sie die email
zum scope
hinzufügen:
FB_SCOPE = ["email"] @app.route("/fb-login") def login(): facebook = requests_oauthlib.OAuth2Session( FB_CLIENT_ID, redirect_uri=URL + "/fb-callback", scope=FB_SCOPE ) authorization_url, _ = facebook.authorization_url(FB_AUTHORIZATION_BASE_URL) return flask.redirect(authorization_url)
Die callback
Route ist etwas komplexer, da Facebook einen Compliance-Fix benötigt:
from requests_oauthlib.compliance_fixes import facebook_compliance_fix @app.route("/fb-callback") def callback(): facebook = requests_oauthlib.OAuth2Session( FB_CLIENT_ID, scope=FB_SCOPE, redirect_uri=URL + "/fb-callback" ) # we need to apply a fix for Facebook here facebook = facebook_compliance_fix(facebook) facebook.fetch_token( FB_TOKEN_URL, client_secret=FB_CLIENT_SECRET, authorization_response=flask.request.url, ) # Fetch a protected resource, ie user profile, via Graph API facebook_user_data = facebook.get( "https://graph.facebook.com/me?fields=id,name,email,picture{url}" ).json() email = facebook_user_data["email"] name = facebook_user_data["name"] picture_url = facebook_user_data.get("picture", {}).get("data", {}).get("url") return f""" User information: <br> Name: {name} <br> Email: {email} <br> Avatar <img src="{picture_url}"> <br> <a href="/">Home</a> """
Wenn Sie jetzt auf Mit Facebook anmelden klicken, sollten Sie in der Lage sein, den gesamten Ablauf zu durchlaufen.
Der vollständige Code ist auf facebook.py.
Fazit
Herzlichen Glückwunsch – Sie haben die SSO-Anmeldung erfolgreich in eine Flask-App integriert!
Der Einfachheit halber werden in diesem Tutorial keine anderen OAuth-Konzepte wie Bereich und Status erwähnt, die wichtig sind, um sich gegen Cross-Site-Request-Forgery-Angriffe zu verteidigen. Sie müssten die Benutzerinformationen wahrscheinlich auch in einer Datenbank speichern, die in diesem Artikel nicht behandelt wird.
Die App muss auch in der Produktion auf https bereitgestellt werden, was heute mit Let's Encrypt recht einfach möglich ist.
Viel Spaß beim OAuthen!