返回文章列表

Flask整合Facebook社群身分驗證

本文介紹如何在 Flask 應用程式中使用 Facebook 進行 OAuth 2.0 身分驗證,讓使用者可以透過 Facebook 帳號登入網站,提升使用者經驗並簡化登入流程。文章涵蓋 Facebook 開發者帳號設定、Flask 應用程式組態、OAuth 流程處理以及程式碼範例。

Web 開發 資安

在網路應用程式開發中,提供便捷的登入方式至關重要。利用 Facebook 等第三方平台的 OAuth 2.0 授權機制,使用者無需額外註冊即可快速登入,有效提升使用者經驗。本文將詳細說明如何在 Flask 應用程式中整合 Facebook 登入功能,包含設定 Facebook 開發者帳號、取得應用程式憑證、組態 Flask 應用程式以及處理 OAuth 流程等步驟,並提供程式碼範例,讓開發者能輕鬆上手。透過 Flask-Dance 函式庫,簡化 OAuth 流程的整合,讓開發者更專注於應用程式邏輯的開發。文章也提及如何在本地端設定 HTTPS 開發環境,確保 OAuth 流程的安全性。

在Flask中使用Facebook進行身分驗證

在許多網站中,使用者可以使用第三方身分驗證服務(如Facebook、Google、Twitter等)登入。這得益於OAuth 2,一個開放的授權標準。在本篇技術中,我們將介紹如何在Flask應用程式中使用Facebook進行OAuth-based的身分驗證。

OAuth 2 的運作原理

OAuth 2允許使用者授權第三方應用程式存取其在其他網站上的資訊,而無需分享密碼。這意味著,第三方客戶端應用程式(你的Flask應用程式)可以透過存取令牌(access token)存取資源伺服器(Facebook等)上的受保護資源。

準備工作

由於OAuth 2需要在SSL環境下運作,因此需要將應用程式組態為使用HTTPS。在本地機器上,可以按照以下步驟進行組態:

  1. 安裝pyopenssl$ pip3 install pyopenssl
  2. app.run()中新增ssl_context='adhoc'引數,例如:app.run(debug=True, ssl_context='adhoc')
  3. 使用https://localhost:5000/存取應用程式,並接受瀏覽器的警告。

注意

在生產環境中,應該從可信的證書頒發機構取得SSL證書。

安裝Flask-Dance和Facebook憑證

  1. 安裝Flask-Dance及其依賴項:$ pip3 install Flask-Dance
  2. 註冊一個Facebook應用程式以用於登入。在Facebook開發者頁面中,記錄下App ID、App secret和Site URL。

組態Facebook身分驗證

步驟1:組態應用程式

my_app/__init__.py中新增以下程式碼:

app.config["FACEBOOK_OAUTH_CLIENT_ID"] = '你的Facebook App ID'
app.config["FACEBOOK_OAUTH_CLIENT_SECRET"] = '你的Facebook App secret'
from my_app.auth.views import facebook_blueprint
app.register_blueprint(auth)
app.register_blueprint(facebook_blueprint)

步驟2:建立Facebook Blueprint

my_app/auth/views.py中新增以下程式碼:

from flask_dance.contrib.facebook import make_facebook_blueprint, facebook
facebook_blueprint = make_facebook_blueprint(scope='email', redirect_to='auth.facebook_login')

#### 內容解密:

此段程式碼建立了一個Facebook Blueprint,用於處理OAuth相關的事務。我們設定了scopeemail,以便使用電子郵件地址作為唯一的使用者名稱。同時,我們設定了redirect_toauth.facebook_login,以便在身分驗證成功後將使用者導向到該URL。

步驟3:處理Facebook登入

新增以下程式碼:

@auth.route("/facebook-login")
def facebook_login():
    if not facebook.authorized:
        return redirect(url_for("facebook.login"))
    resp = facebook.get("/me?fields=name,email")
    user = User.query.filter_by(username=resp.json()["email"]).first()
    if not user:
        user = User(resp.json()["email"], '')

#### 內容解密:

此段程式碼處理了Facebook登入的邏輯。如果使用者尚未授權,則將其導向到Facebook登入頁面。否則,將取得使用者的電子郵件地址和名稱,並查詢資料函式庫中是否存在該使用者。如果不存在,則建立一個新的使用者。

在Flask中進行身分驗證

使用Facebook進行身分驗證

在現代網路應用程式中,簡化使用者登入流程已成為提升使用者經驗的關鍵。透過整合社群媒體登入功能,可以有效減少使用者註冊的阻力。本章節將介紹如何在Flask應用程式中實作Facebook登入功能。

設定Facebook開發者帳戶

  1. 前往Facebook開發者平台建立新的應用程式。
  2. 在應用程式設定中,新增有效的OAuth重新導向URI。
  3. 記錄下應用程式編號(App ID)與應用程式金鑰(App Secret),稍後將用於組態Flask應用程式。

在Flask中組態Facebook登入

首先,在my_app/__init__.py中進行初始設定:

app.config["FACEBOOK_OAUTH_CLIENT_ID"] = "你的Facebook應用程式編號"
app.config["FACEBOOK_OAUTH_CLIENT_SECRET"] = "你的Facebook應用程式金鑰"
from my_app.auth.views import auth, facebook_blueprint
app.register_blueprint(facebook_blueprint)

接下來,在my_app/auth/views.py中建立Facebook藍圖:

from flask_dance.contrib.facebook import make_facebook_blueprint, facebook
facebook_blueprint = make_facebook_blueprint(redirect_to='auth.facebook_login')

處理Facebook登入邏輯

建立一個新的路由處理函式來處理Facebook登入:

@auth.route("/facebook-login")
def facebook_login():
    if not facebook.authorized:
        return redirect(url_for("facebook.login"))
    resp = facebook.get("/me?fields=name,email")
    user = User.query.filter_by(username=resp.json()["email"]).first()
    if not user:
        user = User(resp.json()["email"], '')
        db.session.add(user)
        db.session.commit()
    login_user(user)
    flash('以 %s 的身份透過Facebook登入成功' % resp.json()['name'], 'success')
    return redirect(request.args.get('next', url_for('auth.home')))

更新登入範本

最後,更新login.html範本以包含Facebook登入選項:

<div class="tab-pane" id="social-logins">
    <a href="{{ url_for('auth.facebook_login', next=url_for('auth.home')) }}">透過Facebook登入</a>
</div>

使用Google進行身分驗證

如同Facebook登入,Google登入同樣可以為使用者提供便利的登入方式。

設定Google Cloud Platform

  1. 前往Google Cloud Console建立新的專案。
  2. 在API和服務 > 憑證中,建立新的OAuth 2.0客戶端ID。
  3. 組態OAuth同意畫面並下載JSON金鑰檔案。

在Flask中組態Google登入

my_app/__init__.py中新增Google相關組態:

app.config["GOOGLE_OAUTH_CLIENT_ID"] = "你的Google OAuth客戶端ID"
app.config["GOOGLE_OAUTH_CLIENT_SECRET"] = "你的Google OAuth客戶端金鑰"
app.config["OAUTHLIB_RELAX_TOKEN_SCOPE"] = True
from my_app.auth.views import google_blueprint
app.register_blueprint(google_blueprint)

my_app/auth/views.py中建立Google藍圖:

from flask_dance.contrib.google import make_google_blueprint, google
google_blueprint = make_google_blueprint(scope=["openid", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"], redirect_to='auth.google_login')

處理Google登入邏輯

@auth.route("/google-login")
def google_login():
    if not google.authorized:
        return redirect(url_for("google.login"))
    resp = google.get("/oauth2/v1/userinfo")
    user = User.query.filter_by(username=resp.json()["email"]).first()
    if not user:
        user = User(resp.json()["email"], '')
        db.session.add(user)
        db.session.commit()
    login_user(user)
    flash('以 %s 的身份透過Google登入成功' % resp.json()['name'], 'success')
    return redirect(request.args.get('next', url_for('auth.home')))

更新登入範本以包含Google登入

<a href="{{ url_for('auth.google_login', next=url_for('auth.home')) }}">透過Google登入</a>

使用Twitter進行身分驗證

Twitter提供另一種社群媒體登入選項。

設定Twitter開發者帳戶

  1. 前往Twitter開發者平台建立新的應用程式。
  2. 記錄下API Key和API Key Secret。

在Flask中組態Twitter登入

my_app/__init__.py中新增Twitter相關組態:

app.config["TWITTER_OAUTH_CLIENT_KEY"] = "你的Twitter應用程式ID"
app.config["TWITTER_OAUTH_CLIENT_SECRET"] = "你的Twitter應用程式金鑰"
from my_app.auth.views import twitter_blueprint
app.register_blueprint(twitter_blueprint)

my_app/auth/views.py中建立Twitter藍圖:

from flask_dance.contrib.twitter import make_twitter_blueprint, twitter
twitter_blueprint = make_twitter_blueprint(redirect_to='auth.twitter_login')

本章節介紹瞭如何在Flask應用程式中實作Facebook、Google和Twitter的社群媒體登入功能。透過這些步驟,開發者可以輕鬆地將多種登入選項整合到自己的應用程式中,從而提升使用者的便利性和體驗。

在Flask中進行身分驗證

使用Twitter進行身分驗證

在前面的程式碼中,make_twitter_blueprint 從應用程式組態中讀取 TWITTER_OAUTH_CLIENT_KEYTWITTER_OAUTH_CLIENT_SECRET,並處理所有與 OAuth 相關的操作。由於本範例將使用 Twitter 帳號作為使用者名稱,因此無需設定 scope。

@auth.route("/twitter-login")
def twitter_login():
    if not twitter.authorized:
        return redirect(url_for("twitter.login"))
    resp = twitter.get("account/verify_credentials.json")
    user = User.query.filter_by(username=resp.json()["screen_name"]).first()
    if not user:
        user = User(resp.json()["screen_name"], '')
        db.session.add(user)
        db.session.commit()
    login_user(user)
    flash('Logged in as name=%s using Twitter login' % (resp.json()['name']), 'success')
    return redirect(request.args.get('next', url_for('auth.home')))

內容解密:

  1. 檢查Twitter授權狀態:首先檢查使用者是否已經授權Twitter。如果沒有,則重新導向至Twitter登入頁面。
  2. 取得使用者資訊:使用Twitter的API取得使用者的詳細資訊,包括其螢幕名稱。
  3. 檢查使用者是否存在:查詢本地資料函式庫中是否存在具有相同Twitter帳號的使用者。如果不存在,則建立新使用者並登入;否則,直接登入現有使用者。
  4. 登入使用者:使用login_user函式登入使用者,並顯示成功訊息。

修改登入範本

login.html 中新增以下程式碼以允許Twitter登入:

<a href="{{ url_for('auth.twitter_login', next=url_for('auth.home')) }}">Login via Twitter</a>

使用LDAP進行身分驗證

LDAP是一種用於查詢使用者資訊、憑證和網路指標等的網路協定。最常見的用途是單一登入功能,使用者只需登入一次即可存取多個服務。

步驟1:組態LDAP連線

my_app/__init__.py 中新增以下程式碼:

import ldap
app.config['LDAP_PROVIDER_URL'] = 'ldap://localhost'

def get_ldap_connection():
    conn = ldap.initialize(app.config['LDAP_PROVIDER_URL'])
    return conn

內容解密:

  1. 匯入LDAP模組:匯入 ldap 模組以便與LDAP伺服器互動。
  2. 組態LDAP伺服器URL:設定 LDAP_PROVIDER_URL 為LDAP伺服器的地址。
  3. 建立LDAP連線函式:定義 get_ldap_connection 函式以建立與LDAP伺服器的連線。

使用LDAP進行登入

my_app/auth/views.py 中新增以下程式碼:

@auth.route("/ldap-login", methods=['GET', 'POST'])
def ldap_login():
    if current_user.is_authenticated:
        flash('You are already logged in.', 'info')
        return redirect(url_for('auth.home'))
    form = LoginForm()
    if form.validate_on_submit():
        username = request.form.get('username')
        password = request.form.get('password')
        try:
            conn = get_ldap_connection()
            conn.simple_bind_s('cn=%s,dc=example,dc=org' % username, password)
        except ldap.INVALID_CREDENTIALS:
            flash('Invalid username or password. Please try again.', 'danger')
            return render_template('login.html', form=form)
        user = User.query.filter_by(username=username).first()
        if not user:
            user = User(username, password)
            db.session.add(user)
            db.session.commit()
        login_user(user)
        flash('You have successfully logged in.', 'success')
        return redirect(url_for('auth.home'))
    if form.errors:
        flash(form.errors, 'danger')
    return render_template('login.html', form=form)

內容解密:

  1. 檢查使用者是否已登入:如果使用者已登入,則重新導向至首頁。
  2. 驗證表單資料:驗證登入表單的資料。如果驗證成功,則嘗試使用LDAP伺服器進行身分驗證。
  3. LDAP身分驗證:使用 simple_bind_s 方法對使用者進行身分驗證。如果驗證失敗,則顯示錯誤訊息。
  4. 建立或登入使用者:如果使用者在本地資料函式庫中不存在,則建立新使用者並登入;否則,直接登入現有使用者。

修改登入範本以支援LDAP登入

<ul class="nav nav-tabs">
    <li class="active"><a href="#simple-form" data-toggle="tab">Old Style Login</a></li>
    <li><a href="#social-logins" data-toggle="tab">Social Logins</a></li>
    <li><a href="#ldap-form" data-toggle="tab">LDAP Login</a></li>
</ul>

本章節展示瞭如何在Flask應用程式中實作Twitter和LDAP身分驗證。透過這些範例,開發者可以輕鬆地將多種身分驗證機制整合到自己的應用程式中。