在網路應用程式開發中,提供便捷的登入方式至關重要。利用 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身分驗證。透過這些範例,開發者可以輕鬆地將多種身分驗證機制整合到自己的應用程式中。