#はじめに
Firebase Authを利用してFlaskアプリにログイン機能を導入します。
メールアドレスとパスワードによる認証をサンプルアプリに実装していきます。
Firebaseの設定
はじめに、Firebaseのコンソール上でログインユーザーを登録します。
プロジェクト/アプリの作成
Firebaseのコンソールにログインし、新しいプロジェクトを作ります。
作成したプロジェクトに新しいWEBアプリケーションを追加します。
アプリを追加すると以下のように設定情報が表示されるので、jsonファイルfirebaseConfig.json
に転記します(今回はサンプルアプリであり、記事投稿後にプロジェクトごと削除するので、クリティカルな情報をそのまま載せています^^;)。
{
"apiKey": "AIzaSyAMotj5BYoi8HQbYdw_HqsOTy1NitUTzm8",
"authDomain": "example-fd5bd.firebaseapp.com",
"databaseURL": "https://example-fd5bd.firebaseio.com",
"projectId": "example-fd5bd",
"storageBucket": "example-fd5bd.appspot.com",
"messagingSenderId": "203038233678",
"appId": "1:203038233678:web:86a73fe39a252f8300df1f",
"measurementId": "G-Y6Q7XMDM2V"
}
ユーザーの登録
ログイン用のユーザーを追加します。まず、コンソールのAuthentification > ログイン方法
からメール/パスワードを有効にします。
次に、Authentification > ユーザー
から認証を行うアカウントを追加します。メールアドレスはuser@gmail.com
、パスワードはpassword
としています。
これでFirebaseでの作業は完了です。
Flaskアプリの実装
Firebase側の設定は完了したので、Flaskアプリのコーディングを行います。
インストール
パッケージとしてflask
とpyrebase
をインストールします。pyrebase
はFirebase APIのpythonラッパーです。
pip install flask pyrebase
コード
短いので完成品のコードをそのまま載せます。
ディレクトリ構造
ディレクトリ構造は以下の通りです。app.py
はFlaskアプリで、ログイン画面とインデックス画面があります。認証が行われていない状態ではインデックス画面にアクセスできず、ログイン画面にリダイレクトされます。firebaseConfig.json
は前の手順で作ったもので、app.py
から読み込まれます。
$ tree . -I venv
.
├── app.py
├── firebaseConfig.json
└── templates
├── index.html
└── login.html
1 directory, 4 files
ログイン画面
ログイン画面login.html
は以下の通りです。
フォームからメールアドレスとパスワードを入力しPOSTします。
ログインに失敗しリダイレクトされた場合は、オレンジ色で「メールアドレスまたはパスワードが間違っています」とメッセージが表示されます。
<html>
<head>
<meta charset="utf-8">
<title>Flask app with Firebase authentification</title>
</head>
<body>
<div>
<h1>メールアドレスとパスワードを入力してください</h1>
<form action='login' method='POST'>
<input type='text' name='email' id='email' placeholder='email'/>
<br/>
<input type='password' name='password' id='password' placeholder='password'/>
<br/>
<input type='submit' name='submit'/>
</form>
<h2 style="color:orangered;">{{msg}}</h2>
</div>
</body>
</html>
インデックス画面
index.html
はログイン状態でのみアクセスできます。ユーザーのメールアドレスを表示しています。ログアウトを押すと、ログイン画面にリダイレクトされます。
<html>
<head>
<meta charset="utf-8">
<title>Flask app with Firebase authentification</title>
</head>
<body>
<div>
<h1>{{usr}}さん、こんにちは!</h1>
<a href="/logout">ログアウト</a>
</div>
</body>
</html>
Flaskアプリ
アプリ本体のコードの説明です。はじめにfirebaseConfig.json
を読み込み、初期化を行います。アクセス可能なルートとしてlogin
、index
、logout
の3つがあります。それぞれの機能は以下の通りです。
login()
では、メソッドがGET
だった場合にはlogin.html
を表示し、メソッドがPOSTだった場合にはリクエストフォームのパラメタemail
とpassword
を取り出しsign_in_with_email_and_password
によりFirebase認証を行います。失敗した場合はエラーとなるので、例外処理でログイン画面にリダイレクトします。成功した場合は、セッション変数にユーザーのメールアドレスを格納し、インデックス画面にリダイレクトします。
index()
では、セッション変数が存在するかどうかでログインしているかどうかを判定しています。存在していない場合はログイン画面にリダイレクトし、存在する場合はindex.html
を表示させます。
logout()
では、セッション変数を削除してログイン画面にリダイレクトします。
from flask import Flask, request, jsonify, render_template, redirect, url_for, session
import pyrebase
import json, os
with open("firebaseConfig.json") as f:
firebaseConfig = json.loads(f.read())
firebase = pyrebase.initialize_app(firebaseConfig)
auth = firebase.auth()
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template("login.html",msg="")
email = request.form['email']
password = request.form['password']
try:
user = auth.sign_in_with_email_and_password(email, password)
session['usr'] = email
return redirect(url_for('index'))
except:
return render_template("login.html", msg="メールアドレスまたはパスワードが間違っています。")
@app.route("/", methods=['GET'])
def index():
usr = session.get('usr')
if usr == None:
return redirect(url_for('login'))
return render_template("index.html", usr=usr)
@app.route('/logout')
def logout():
del session['usr']
return redirect(url_for('login'))
# run the app.
if __name__ == "__main__":
app.debug = True
app.run(port=5000)
まとめ
Firebase認証を使ってメールアドレスとパスワードによるログイン機能をFlaskアプリに導入することが出来ました。ログイン機能が必要になったときに手軽に導入できるのでおすすめです。アカウントの追加・停止、パスワード再発行などの操作をプラットフォーム上で行えるので、管理のコストも抑えられます。
ただし、Firebaseはモバイルアプリのプラットフォームなので、今回紹介したようにFlaskのセッション管理機能と組み合わせて使うことは珍しいかもしれません。