Cara Membuat Tombol SSO – Tutorial Login Flask
Diterbitkan: 2022-03-11Aplikasi seringkali membutuhkan fungsionalitas login agar pengguna dapat menyimpan data, membuat profil mereka sendiri, atau mungkin hanya untuk membatasi akses ke sumber daya yang sensitif. Dalam aplikasi modern, pengguna berharap memiliki fitur terkait login standar seperti verifikasi email, reset kata sandi, atau otentikasi multi-faktor. Fitur-fitur ini, meskipun diperlukan, tidak mudah untuk diperbaiki dan biasanya bukan urusan utama aplikasi.
Di sisi pengguna, mereka mungkin tidak ingin melalui proses pendaftaran yang panjang karena mereka harus membuat dan mengingat pasangan email dan kata sandi lainnya. Tanpa pengelola kata sandi yang tepat, pengguna cenderung menggunakan kembali kata sandi yang sama yang sangat buruk dalam hal keamanan.
Sistem masuk tunggal (SSO), sebagian besar dikenal pengguna sebagai login dengan tombol media sosial , diciptakan sebagai solusi untuk masalah ini. Bagi pengguna, tidak melalui proses pendaftaran yang menyakitkan itu mudah. Untuk bisnis, menghilangkan gesekan bagi pengguna selalu merupakan kemenangan besar—dan, bagi pengembang, semua fitur terkait login kini didelegasikan ke penyedia identitas (Facebook, Google, Twitter, dll.), artinya lebih sedikit kode! Aplikasi Anda hanya mempercayai penyedia identitas untuk melakukan tugasnya memverifikasi identitas pengguna.
SSO biasanya didukung oleh protokol OpenId Connect (OIDC) atau SAML. SAML digunakan sebagian besar dalam aplikasi perusahaan. OIDC dibangun di atas OAuth2 dan digunakan oleh penyedia identitas sosial seperti Facebook, Google, dll. Dalam posting ini, kita akan fokus pada protokol OIDC/OAuth2.
Dalam tutorial login Flask ini, kita akan menulis panduan langkah demi langkah untuk menambahkan tombol login SSO ke dalam aplikasi Flask dengan SimpleLogin dan Facebook sebagai penyedia identitas. Ini dapat dilakukan tanpa menggunakan pustaka eksternal apa pun, tetapi untuk menyederhanakan kerumitan OAuth, kami akan menggunakan Requests-OAuthlib, pustaka untuk mengintegrasikan penyedia OAuth. Jika Anda tertarik untuk menerapkan SSO dari awal, silakan periksa Implementasi Login SSO – cara mentahnya .
Di akhir artikel ini, Anda harus memiliki aplikasi Flask yang memiliki halaman berikut:
- Beranda yang menampilkan tombol masuk
- Halaman informasi pengguna di mana, setelah login berhasil, pengguna akan dapat melihat informasi seperti nama, email, dan avatar
Semua kode untuk tutorial ini dapat ditemukan di repositori flask-social-login-example.
Demo juga tersedia di sini. Jangan ragu untuk me-remix kode di Glitch.
Langkah 1: Aplikasi Bootstrap Flask
Instal flask
dan Requests-OAuthlib
. Anda juga dapat menggunakan virtualenv
atau pipenv
untuk mengisolasi lingkungan.
pip install flask request_oauthlib
Buat app.py
dan rute yang menampilkan tombol login di halaman beranda:
import flask app = flask.Flask(__name__) @app.route("/") def index(): return """ <a href="/login">Login</a> """ if __name__ == '__main__': app.run(debug=True)
Mari jalankan aplikasi ini dan verifikasi semuanya berfungsi dengan baik:
python app.py
Anda akan melihat halaman ini saat membuka http://localhost:5000. Kode lengkapnya ada di step1.py.
Langkah 2: Kredensial Penyedia Identitas
Saat ini ada ratusan (bahkan ribuan) penyedia identitas dengan yang paling populer adalah Facebook, Google, GitHub, dan Instagram. Untuk posting ini, SimpleLogin dipilih karena keramahan pengembangnya. Kode yang sama akan berfungsi dengan penyedia identitas OAuth2 apa pun. (Penafian: Saya kebetulan adalah salah satu pendiri SimpleLogin, yang—ahem—mungkin menjadi faktor dalam keputusan saya untuk menggunakannya.)
Silakan menuju ke SimpleLogin dan buat akun jika Anda belum memilikinya, lalu buat aplikasi baru di tab Pengembang.
Pada halaman detail aplikasi, harap salin AppID dan AppSecret Anda dan simpan ke dalam lingkungan variabel. Dalam terminologi OAuth, klien sebenarnya berarti aplikasi pihak ketiga, yaitu aplikasi Anda. Kita dapat menempatkan nilai-nilai ini secara langsung dalam kode, tetapi praktik yang baik adalah menyimpan kredensial ke dalam variabel lingkungan. Ini juga merupakan faktor ketiga dalam Dua Belas Faktor.
export CLIENT_ID={your AppID} export CLIENT_SECRET={your AppSecret}
Di app.py
, tambahkan baris ini di atas file untuk mendapatkan client id
client secret
.
import os CLIENT_ID = os.environ.get("CLIENT_ID") CLIENT_SECRET = os.environ.get("CLIENT_SECRET")
Harap tambahkan juga URL OAuth ini di bagian atas app.py
yang akan digunakan pada langkah berikutnya. Mereka juga dapat disalin di halaman titik akhir 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"
Karena kami tidak ingin khawatir tentang menyiapkan SSL sekarang, beri tahu Requests-OAuthlib
bahwa boleh saja menggunakan HTTP biasa:
# This allows us to use a plain HTTP callback os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
Seperti biasa, kode untuk langkah ini ada di step2.py.
Langkah 3: Pengalihan Masuk
Ketika pengguna mengklik tombol login:
- Pengguna akan diarahkan ke halaman otorisasi penyedia login identitas menanyakan apakah pengguna ingin membagikan informasi mereka dengan aplikasi Anda.
- Setelah disetujui pengguna, mereka kemudian akan diarahkan kembali ke halaman di aplikasi Anda bersama dengan
code
di URL yang akan digunakan aplikasi Anda untuk ditukar denganaccess token
yang memungkinkan Anda nanti mendapatkan informasi pengguna dari penyedia layanan.
Oleh karena itu, kita memerlukan dua rute: rute login
yang mengarahkan pengguna ke penyedia identitas dan rute callback
yang menerima code
dan menukarnya dengan access token
. Rute panggilan balik juga bertanggung jawab untuk menampilkan informasi pengguna.

@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> """
Mengklik tombol login akan membawa Anda melalui alur berikut. Kode lengkapnya dapat ditemukan di GitHub di step3.py.
Masuk dengan Facebook
Pengaturan login Facebook, Google, dan Twitter agak rumit dan memerlukan langkah-langkah tambahan seperti menyiapkan SSL atau memilih cakupan yang tepat. Ini berada di luar cakupan artikel ini.
Terlepas dari UI yang canggih, bagian tersulit dalam mengintegrasikan Facebook mungkin adalah menemukan cara untuk menyajikan aplikasi web Anda di HTTPS secara lokal karena versi baru SDK Facebook tidak mengizinkan HTTP biasa lokal. Saya sarankan menggunakan Ngrok, alat gratis untuk memiliki URL HTTPS cepat.
Langkah 1: Buat Aplikasi Facebook
Silakan buka https://developers.facebook.com
dan buat aplikasi baru:
Kemudian pilih "Integrate Facebook Login" di layar berikutnya:
Langkah 2: Kredensial OAuth Facebook
Klik “Pengaturan/Dasar” di sebelah kiri, dan salin ID Aplikasi dan Rahasia Aplikasi . Mereka sebenarnya adalah OAuth client-id
dan client-secret
.
Perbarui client-id
dan client-secret
.
export FB_CLIENT_ID={your facebook AppId} export FB_CLIENT_SECRET={your facebook AppSecret}
Perbarui AUTHORIZATION_BASE_URL dan TOKEN_URL:
FB_AUTHORIZATION_BASE_URL = "https://www.facebook.com/dialog/oauth" FB_TOKEN_URL = "https://graph.facebook.com/oauth/access_token"
Beranda:
@app.route("/") def index(): return """ <a href="/fb-login">Login with Facebook</a> """
Langkah 3: Masuk dan Titik Akhir Panggilan Balik
Jika aplikasi disajikan di belakang ngrok
menggunakan perintah ngrok http 5000
, kita perlu mengatur URL saat ini ke URL ngrok.
# Your ngrok url, obtained after running "ngrok http 5000" URL = "https://abcdefgh.ngrok.io"
Pastikan untuk menambahkan url ke Login/Pengaturan Facebook Anda, pengaturan URI Pengalihan OAuth yang valid:
Untuk memiliki akses ke email pengguna, Anda perlu menambahkan email
ke dalam 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)
Rute callback
sedikit lebih rumit karena Facebook memerlukan perbaikan kepatuhan:
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> """
Sekarang ketika mengklik Masuk dengan Facebook, Anda harus dapat melalui seluruh alur.
Kode lengkapnya ada di facebook.py.
Kesimpulan
Selamat—Anda telah berhasil mengintegrasikan login SSO ke dalam aplikasi Flask!
Demi kesederhanaan, tutorial ini tidak menyebutkan konsep OAuth lain seperti cakupan dan status, yang penting untuk dipertahankan dari serangan pemalsuan permintaan lintas situs. Anda juga mungkin perlu menyimpan info pengguna dalam database yang tidak tercakup dalam artikel ini.
Aplikasi ini juga perlu disajikan di https pada produksi, yang dapat dengan mudah dilakukan hari ini dengan Let's Encrypt.
Selamat OAuthing!