このチュートリアルでは、Firebase Authentication、App Engine スタンダード環境、および Cloud Datastore を使用してユーザー認証情報を取得、検証、保存する方法を説明します。
本書では、Firenotes という名前のシンプルなメモ編集アプリケーションの使い方について説明します。このアプリケーションは、ユーザーのメモを個人用のノートブックに保存します。ノートブックはユーザーごとに保存され、各ユーザーの一意の Firebase Authentication ID によって識別されます。このアプリケーションには次のコンポーネントがあります。
フロントエンドはログイン ユーザー インターフェースを構成し、Firebase Authentication ID を取得します。また、認証状態の変化を処理し、ユーザーにメモを表示します。
FirebaseUI は、ユーザー ログイン、複数のプロバイダの 1 つのアカウントへのリンク、パスワードの回復などを処理するオープンソースのドロップイン ソリューションです。認証のおすすめの方法を実装して、スムーズで安全なログイン方式を実現します。
バックエンドは、ユーザーの認証状態を検証し、ユーザーのプロフィール情報およびメモを返します。
このアプリケーションは、NDB クライアント ライブラリを使用してユーザー認証情報を Cloud Datastore に保存しますが、認証情報は任意のデータベースに保存することもできます。
次の図は、フロントエンドとバックエンドが相互に通信する方法、およびユーザー認証情報が Firebase からデータベースにどのように移動するかを示しています。Firenotes は、Flask ウェブ アプリケーション フレームワークをベースにしています。サンプルアプリが Flask を使用しているのは、単純で使いやすいからです。ただし、ここで説明する概念やテクノロジーは、使用するフレームワークに関係なく、適用可能です。
目標
このチュートリアルの目標は次のとおりです。
- Firebase Authentication ユーザー インターフェースを構成する。
- Firebase ID トークンを取得し、サーバー側の認証を使用して検証する。
- ユーザー認証情報と関連データを Cloud Datastore に保存する。
- NDB クライアント ライブラリを使用してデータベースに問い合わせる。
- アプリを App Engine にデプロイする。
費用
このチュートリアルでは、以下の Google Cloud Platform(GCP)の課金対象コンポーネントを使用します。
- Cloud Datastore
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。 GCP を初めて使用される方は、無料トライアルをご利用いただけます。
始める前に
- Git、Python 2.7、および virtualenv をインストールします。最新バージョンの Python のインストールなど Python 開発環境の設定の詳細については、GCP の Python 開発環境の設定を参照してください。
-
Google アカウントにログインします。
Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。
-
GCP Console のプロジェクト セレクタのページで、GCP プロジェクトを選択または作成します。
- Cloud SDK をインストールして初期化します。
すでに SDK をインストールして別のプロジェクトに初期化してある場合は、gcloud
プロジェクトを Firenotes に使用している App Engine プロジェクト ID に設定します。gcloud
ツールを使用してプロジェクトを更新するための個別のコマンドについては、Cloud SDK 構成の管理をご覧ください。
サンプルアプリのクローンを作成する
サンプルをローカルマシンにダウンロードするには、次のようにします。
サンプル アプリケーション レポジトリをローカルマシンにクローン作成します。
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
または、zip ファイルとしてサンプルをダウンロードして解凍することもできます。
サンプルコードが含まれるディレクトリに移動します。
FirebaseUI を設定して ID プロバイダを有効にするには、次のようにします。cd python-docs-samples/appengine/standard/firebase/firenotes
Firebase をアプリに追加する手順は次のとおりです。
- Firebase コンソールで Firebase プロジェクトを作成します。
- 既存の Firebase プロジェクトがない場合は、[プロジェクトを追加] をクリックし、既存の Google Cloud Platform プロジェクト名または新しいプロジェクト名を入力します。
- 既存の Firebase プロジェクトを使用する場合は、そのプロジェクトをコンソールから選択します。
- プロジェクトの概要ページで、[ウェブアプリに Firebase を追加] をクリックします。プロジェクトにアプリがある場合は、プロジェクトの概要ページで [アプリを追加] を選択します。
プロジェクトのカスタマイズ済みのコード スニペットの
Initialize Firebase
セクションを使用して、frontend/main.js
ファイルの次のセクションを入力します。
- Firebase コンソールで Firebase プロジェクトを作成します。
backend/app.yaml
ファイルを編集し、Firebase プロジェクト ID を環境変数に入力します。frontend/main.js
ファイルで、ユーザーに提供するプロバイダを選択して FirebaseUI ログイン ウィジェットを構成します。[認証] > [ログイン方法] をクリックして、選択したプロバイダが Firebase コンソール内に保持されるようにします。その後、[ログイン プロバイダ] で、カーソルをプロバイダの上に移動し、鉛筆アイコンをクリックします。
[有効] ボタンを切り替え、サードパーティ ID プロバイダの場合は、プロバイダのデベロッパー サイトからプロバイダ ID とシークレットを入力します。Firebase ドキュメントの、Facebook、Twitter、および GitHub ガイドの「始める前に」に、具体的な指示が記載されています。プロバイダを有効にしたら、[保存] をクリックします。
Firebase コンソールの [承認済みドメイン] で [ドメインを追加] をクリックし、App Engine のアプリのドメインを次の形式で入力します。
[PROJECT_ID].appspot.com
ドメイン名の前に
http://
を付けないでください。
依存関係のインストール
backend
ディレクトリに移動して、アプリケーション セットアップを完了します。cd backend/
依存関係をプロジェクトの
lib
ディレクトリにインストールします。pip install -t lib -r requirements.txt
appengine_config.py
では、vendor.add()
メソッドによってライブラリがlib
ディレクトリに登録されます。
アプリケーションをローカルで実行する
アプリケーションをローカルで実行するには、App Engine ローカル開発用サーバーを使用します。
main.js
で次の URL をbackendHostURL
として追加します。http://localhost:8081
アプリケーションのルート ディレクトリに移動します。その後で、開発用サーバーを始動します。
dev_appserver.py frontend/app.yaml backend/app.yaml
ウェブブラウザで http://localhost:8080/ にアクセスします。
サーバーでユーザーを認証する
これで、プロジェクトのセットアップと開発用のアプリケーションの初期化が完了しました。コードを辿りながら、サーバー上で Firebase ID トークンを取得して確認する方法を見てみましょう。
Firebase から ID トークンを取得する
サーバー側の認証の最初の手順は、アクセス トークンの取得と確認です。認証リクエストは、Firebase からの onAuthStateChanged()
リスナーを使用して処理されます。
ユーザーがログインすると、コールバックの Firebase getToken()
メソッドが JSON Web Token(JWT)形式で Firebase ID トークンを返します。
サーバーでトークンを確認する
ユーザーがログインすると、フロントエンド サービスが AJAX GET
リクエストを通してユーザーのノートブック内の既存のメモをフェッチします。これには、ユーザーのデータにアクセスする許可が必要なため、JWT が Bearer
スキーマを使用してリクエストの Authorization
ヘッダーで送信されます。
クライアントがサーバー データにアクセスするには、トークンが Firebase によって署名されていることを、サーバーで確認する必要があります。このトークンは、Python 用の Google 認証ライブラリを使用して確認できます。認証ライブラリの verify_firebase_token
関数を使用して、署名なしトークンを確認し、要求を抽出します。
各 ID プロバイダは別々の要求セットを送信しますが、それぞれに一意のユーザー ID を持つ 1 つ以上の sub
要求と name
や email
などの特定のプロフィール情報を提供する 1 つの要求が含まれています。これを使用して、アプリのユーザー エクスペリエンスをパーソナライズすることができます。
Cloud Datastore でのユーザーデータの管理
ユーザーを認証したら、それに関するユーザーのデータを保存してログイン セッションが終わるまで維持する必要があります。以降のセクションでは、メモを Cloud Datastore エンティティとして保存し、それらをユーザー ID で区別する方法について説明します。
ユーザー データを保存するエンティティの作成
Cloud Datastore では、整数や文字列などの特定のプロパティを使用し、NDB モデルクラスを宣言することによってエンティティを作成できます。Cloud Datastore は、種類を基準にしてエンティティにインデックスを付けます。Firenotes の場合、各エンティティの種類は Note
です。クエリを出すために、各 Note
はキー名付きで保存されます。キー名は、前のセクションの sub
要求から取得されたユーザー ID です。
次のコードは、エンティティのプロパティを設定する方法を示し、エンティティの作成時にモデルクラスとしてコンストラクタ メソッドを使用する方法と、作成後に個別のプロパティを割り当てる方法の両方が示されています。
新しく作成した Note
を Cloud Datastore に書き込むには、note
オブジェクトに対して put()
メソッドを呼び出します。
ユーザー データの取得
特定のユーザー ID に関連付けられたユーザー データを取得するには、NDB query()
メソッドを使用してデータベースを検索し、同じエンティティ グループ内のメモを見つけます。同じグループ内のエンティティ、つまり、祖先パスは、共通のキー名(この場合はユーザー ID)を共有します。
クエリ データをフェッチして、メモをクライアントに表示することができます。
アプリのデプロイ
これで Firebase Authentication と App Engine アプリケーションが正常に統合されました。本番環境で動作しているアプリケーションを確認するには、次の手順を実行します。
main.js
のバックエンド ホスト URL をhttps://backend-dot-[PROJECT_ID].appspot.com
に変更します。[PROJECT_ID]
は実際のプロジェクト ID に置き換えてください。Cloud SDK コマンドライン インターフェースを使用してアプリケーションをデプロイします。
gcloud app deploy backend/index.yaml frontend/app.yaml backend/app.yaml
https://[PROJECT_ID].appspot.com
で実動しているアプリケーションを表示します。
クリーンアップ
このチュートリアルで使用したリソースについて GCP アカウントに課金されないようにするには、App Engine プロジェクトを削除します。
プロジェクトの削除
課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。
プロジェクトを削除する手順は次のとおりです。
- GCP Console で [プロジェクト] ページに移動します。
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。
次のステップ
Google Cloud Platform のその他の機能を試してみます。チュートリアルをご覧ください。