Cum se creează un buton SSO – Un tutorial de conectare la Flask

Publicat: 2022-03-11

Aplicațiile au adesea nevoie de funcționalitate de conectare, astfel încât utilizatorii să poată salva date, să-și creeze propriile profiluri sau poate doar pentru a restricționa accesul la resursele sensibile. Într-o aplicație modernă, utilizatorii se așteaptă să aibă caracteristici standard legate de autentificare, cum ar fi verificarea e-mailului, resetarea parolei sau autentificarea cu mai mulți factori. Aceste caracteristici, deși necesare, nu sunt ușor de realizat corect și, de obicei, nu sunt principalele activități ale aplicației.

În ceea ce privește utilizatorii, este posibil ca aceștia să nu dorească să treacă prin procesul de înregistrare îndelungat, deoarece trebuie să creeze și să-și amintească încă o pereche de e-mail și parolă. Fără un manager de parole adecvat, utilizatorii tind să refolosească aceeași parolă, ceea ce este îngrozitor în ceea ce privește securitatea.

Single sign-on (SSO), cunoscut mai ales utilizatorilor ca autentificare cu butoane de socializare , a fost inventat ca o soluție la această problemă. Pentru utilizatori, a nu trece printr-un alt proces dureros de înregistrare a fost ușor. Pentru companii, eliminarea fricțiunilor pentru utilizatori este întotdeauna un câștig uriaș și, pentru dezvoltatori, toate funcțiile legate de autentificare sunt acum delegate furnizorului de identitate (Facebook, Google, Twitter etc.), ceea ce înseamnă mai puțin cod! Aplicația dvs. pur și simplu are încredere în furnizorul de identitate care își face treaba de a verifica identitatea utilizatorului.

SSO este de obicei alimentat de protocolul OpenId Connect (OIDC) sau SAML. SAML este folosit mai ales în aplicațiile de întreprindere. OIDC este construit pe OAuth2 și folosit de furnizorii de identitate socială precum Facebook, Google etc. În această postare, ne vom concentra asupra protocolului OIDC/OAuth2.

În acest tutorial de conectare Flask, vom scrie un ghid pas cu pas pentru a adăuga un buton de conectare SSO într-o aplicație Flask cu SimpleLogin și Facebook ca furnizor de identitate. Acest lucru se poate face fără a utiliza nicio bibliotecă externă, dar pentru a simplifica complexitatea OAuth, vom folosi Requests-OAuthlib, o bibliotecă pentru a integra furnizorii OAuth. Dacă sunteți interesat să implementați SSO de la zero, vă rugăm să consultați Implementarea SSO Login – modul brut .

La sfârșitul acestui articol, ar trebui să aveți o aplicație Flask care are următoarele pagini:

  • Pagina de pornire cu butoane de conectare
  • Pagina de informații despre utilizator în care, după conectarea cu succes, utilizatorul va putea vedea informații precum numele, e-mailul și avatarul

Tot codul pentru acest tutorial poate fi găsit în depozitul flask-social-login-example.

Un demo este, de asemenea, disponibil aici. Simțiți-vă liber să remixați codul pe Glitch.

Pasul 1: aplicația Bootstrap Flask

Instalați flask și Requests-OAuthlib . De asemenea, puteți utiliza virtualenv sau pipenv pentru a izola mediul.

pip install flask requests_oauthlib

Creați app.py și traseul care afișează un buton de conectare pe pagina de pornire:

 import flask app = flask.Flask(__name__) @app.route("/") def index(): return """ <a href="/login">Login</a> """ if __name__ == '__main__': app.run(debug=True)

Să rulăm această aplicație și să verificăm că totul funcționează bine:

 python app.py

Ar trebui să vedeți această pagină când deschideți http://localhost:5000. Codul complet este pe step1.py.

Conectați-vă cu SimpleLogin

Pasul 2: Acreditarea furnizorului de identitate

În prezent, există sute (dacă nu mii) de furnizori de identitate, cei mai populari fiind Facebook, Google, GitHub și Instagram. Pentru această postare, SimpleLogin este ales din cauza ușurinței sale pentru dezvoltatori. Totuși, același cod va funcționa cu orice furnizor de identitate OAuth2. (Declinarea răspunderii: se întâmplă să fiu co-fondatorul SimpleLogin, ceea ce — ahem — poate fi un factor în decizia mea de a-l folosi.)

Vă rugăm să mergeți la SimpleLogin și să creați un cont dacă nu aveți deja unul, apoi creați o nouă aplicație în fila Dezvoltator.

Pe pagina de detalii a aplicației, copiați AppID și AppSecret și salvați-le în mediul variabil. În terminologia OAuth, client înseamnă de fapt o aplicație terță parte, adică aplicația dvs. Putem pune aceste valori direct în cod, dar este o practică bună să salvați acreditările în variabilele de mediu. Acesta este, de asemenea, al treilea factor din cei Doisprezece Factori.

Setări OAuth2

 export CLIENT_ID={your AppID} export CLIENT_SECRET={your AppSecret}

În app.py , adăugați aceste rânduri deasupra fișierului pentru a obține client id client secret .

 import os CLIENT_ID = os.environ.get("CLIENT_ID") CLIENT_SECRET = os.environ.get("CLIENT_SECRET")

Vă rugăm să adăugați, de asemenea, aceste adrese URL OAuth în partea de sus a app.py , care vor fi utilizate în pasul următor. Ele pot fi copiate și pe pagina de puncte finale OAuth.

 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"

Deoarece nu vrem să ne facem griji despre configurarea SSL acum, să spunem Requests-OAuthlib că este în regulă să folosiți HTTP simplu:

 # This allows us to use a plain HTTP callback os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"

Ca de obicei, codul pentru acest pas este pe step2.py.

Pasul 3: Redirecționare autentificare

Când un utilizator face clic pe butonul de conectare:

  1. Utilizatorul va fi redirecționat către pagina de autorizare a furnizorului de autentificare pentru identitate, întrebând dacă utilizatorul dorește să-și partajeze informațiile cu aplicația dvs.
  2. După aprobarea utilizatorului, aceștia vor fi apoi redirecționați înapoi către o pagină din aplicația dvs. împreună cu un code în adresa URL pe care aplicația dvs. îl va folosi pentru a schimba un access token care vă permite ulterior să obțineți informații despre utilizator de la furnizorul de servicii.

Avem nevoie, așadar, de două rute: o rută de login care redirecționează utilizatorul către furnizorul de identitate și o rută de callback care primește code și îl schimbă cu un access token . Ruta de apel invers este, de asemenea, responsabilă pentru afișarea informațiilor despre utilizator.

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

Făcând clic pe butonul de autentificare ar trebui să vă aducă prin următorul flux. Codul complet poate fi găsit pe GitHub la step3.py.

Conectați-vă cu SimpleLogin pentru a permite informații despre utilizator

Logheaza-te cu Facebook

Configurarea autentificării Facebook, Google și Twitter este puțin complexă și necesită pași suplimentari, cum ar fi configurarea SSL sau alegerea domeniilor potrivite. Acestea depășesc domeniul de aplicare al acestui articol.

În afară de o interfață de utilizare sofisticată, cea mai grea parte a integrării Facebook ar putea fi găsirea unei modalități de a vă servi aplicația web pe HTTPS la nivel local, deoarece noua versiune a SDK-ului Facebook nu permite HTTP simplu local. Recomand să folosiți Ngrok, un instrument gratuit pentru a avea o adresă URL HTTPS rapidă.

Pasul 1: Creați o aplicație Facebook

Vă rugăm să https://developers.facebook.com și să creați o nouă aplicație:

Creați un nou ID de aplicație

Apoi alegeți „Integrare autentificare Facebook” pe următorul ecran:

Integrați autentificarea Facebook

Pasul 2: Acreditare OAuth Facebook

Faceți clic pe „Setări/De bază” din stânga și copiați ID -ul aplicației și Secretul aplicației . Ele sunt de fapt OAuth client-id și client-secret .

Setări de bază

Actualizați client-id și client-secret .

 export FB_CLIENT_ID={your facebook AppId} export FB_CLIENT_SECRET={your facebook AppSecret}

Actualizați AUTHORIZATION_BASE_URL și TOKEN_URL:

 FB_AUTHORIZATION_BASE_URL = "https://www.facebook.com/dialog/oauth" FB_TOKEN_URL = "https://graph.facebook.com/oauth/access_token"

Pagina de start:

 @app.route("/") def index(): return """ <a href="/fb-login">Login with Facebook</a> """

Pasul 3: Puncte finale de conectare și apel invers

Dacă aplicația este difuzată în spatele ngrok folosind comanda ngrok http 5000 , trebuie să setăm adresa URL curentă la adresa URL ngrok.

 # Your ngrok url, obtained after running "ngrok http 5000" URL = "https://abcdefgh.ngrok.io"

Asigurați-vă că adăugați adresa URL la Login/Setări Facebook, setarea Valid OAuth Redirect URIs:

URI de redirecționare OAuth valide

Pentru a avea acces la un e-mail de utilizator, trebuie să adăugați e- email în domeniul de scope :

 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)

Ruta de callback este puțin mai complexă, deoarece Facebook necesită o remediere a conformității:

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

Acum, când faceți clic pe Conectare cu Facebook, ar trebui să puteți parcurge întregul flux.

Conectați-vă cu procesul Facebook

Codul complet este pe facebook.py.

Concluzie

Felicitări – ați integrat cu succes autentificarea SSO într-o aplicație Flask!

Din motive de simplitate, acest tutorial nu menționează alte concepte OAuth, cum ar fi domeniul de aplicare și starea, care sunt importante pentru a le apăra împotriva atacurilor de falsificare a cererilor pe mai multe site-uri. De asemenea, probabil ar trebui să stocați informațiile despre utilizator într-o bază de date care nu este tratată în acest articol.

De asemenea, aplicația trebuie să fie difuzată pe https în producție, ceea ce se poate face destul de ușor astăzi cu Let's Encrypt.

OAuthing fericit!