34
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FlaskアプリにFirebase Authを利用したログイン機能を実装する

Last updated at Posted at 2019-12-26

#はじめに
Firebase Authを利用してFlaskアプリにログイン機能を導入します。
メールアドレスとパスワードによる認証をサンプルアプリに実装していきます。

Firebaseの設定

はじめに、Firebaseのコンソール上でログインユーザーを登録します。

プロジェクト/アプリの作成

Firebaseのコンソールにログインし、新しいプロジェクトを作ります。
スクリーンショット 2019-12-26 14.17.24.png

作成したプロジェクトに新しいWEBアプリケーションを追加します。
スクリーンショット 2019-12-21 17.44.25.png
アプリを追加すると以下のように設定情報が表示されるので、jsonファイルfirebaseConfig.jsonに転記します(今回はサンプルアプリであり、記事投稿後にプロジェクトごと削除するので、クリティカルな情報をそのまま載せています^^;)。

スクリーンショット 2019-12-24 19.27.20.png
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 > ログイン方法からメール/パスワードを有効にします。
スクリーンショット 2019-12-24 19.34.53.png

次に、Authentification > ユーザーから認証を行うアカウントを追加します。メールアドレスはuser@gmail.com、パスワードはpasswordとしています。
スクリーンショット 2019-12-24 19.35.26.png
これでFirebaseでの作業は完了です。

Flaskアプリの実装

Firebase側の設定は完了したので、Flaskアプリのコーディングを行います。

インストール

パッケージとしてflaskpyrebaseをインストールします。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します。
ログインに失敗しリダイレクトされた場合は、オレンジ色で「メールアドレスまたはパスワードが間違っています」とメッセージが表示されます。

templates/login.html
<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>

ブラウザでは以下のように表示されます。
スクリーンショット 2019-12-26 14.14.07.png

インデックス画面

index.htmlはログイン状態でのみアクセスできます。ユーザーのメールアドレスを表示しています。ログアウトを押すと、ログイン画面にリダイレクトされます。

templates/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>

ブラウザでは以下のように表示されます。
スクリーンショット 2019-12-26 14.13.55.png

Flaskアプリ

アプリ本体のコードの説明です。はじめにfirebaseConfig.jsonを読み込み、初期化を行います。アクセス可能なルートとしてloginindexlogoutの3つがあります。それぞれの機能は以下の通りです。

login()では、メソッドがGETだった場合にはlogin.htmlを表示し、メソッドがPOSTだった場合にはリクエストフォームのパラメタemailpasswordを取り出しsign_in_with_email_and_passwordによりFirebase認証を行います。失敗した場合はエラーとなるので、例外処理でログイン画面にリダイレクトします。成功した場合は、セッション変数にユーザーのメールアドレスを格納し、インデックス画面にリダイレクトします。

index()では、セッション変数が存在するかどうかでログインしているかどうかを判定しています。存在していない場合はログイン画面にリダイレクトし、存在する場合はindex.htmlを表示させます。

logout()では、セッション変数を削除してログイン画面にリダイレクトします。

app.py
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のセッション管理機能と組み合わせて使うことは珍しいかもしれません。

34
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?