firebase でユーザー認証
Googleが提供するサービスに firebase というものがあります。サーバーサイドのいろいろな処理を提供してくれるサービスですが、今回はユーザー認証処理についての実装方法をまとめます。
あるWebアプリにユーザー認証を実装するとなると、ユーザー情報の管理、サーバーやDBの構築等様々な準備が必要ですが、firebaseを使えばこれら使わずサーバーレスで実装できます。
firebaseは無料プランがあり、それなりの規模でも無料で使えるので便利です。Googleアカウントがあれば、特に登録等も不要です。
firebase を始める
まずは firebase のプロジェクトを作成します。トップページの「使ってみる」ボタンからプロジェクト作成に進みます。
プロジェクトを追加から新規でプロジェクトを作成します。
プロジェクト名はここでは仮に「my-sample-project」とします。
「プロジェクトを作成」をクリックしたらプロジェクトの作成処理が開始します。
プロジェクトの作成処理が完了すると、firebaseのコンソール画面に飛ばされます。
プロジェクトの設定値を確認する
左の設定から、プロジェクトの設定確認しておきます。ここの情報が後で必要になるので控えておきます。
Firebase Authentication
Firebase Authentication は、firebase での認証処理を行うための機能です。
Firebase Authentication では、パスワード、電話番号、一般的なフェデレーション ID プロバイダ(Google、Facebook、Twitter)などを使用した認証を行うことができます。
上記ページを参考に、Webページにログイン認証機能を実装していきます。
認証方法の追加
Firebase コンソールで [Authentication] セクションを開き、ログイン方法を設定ボタンから、メールアドレスとパスワードによる認証を有効にします。
そのほか、さまざまなプロバイダのIDと連携させることもかのですが、今回はメールアドレスとパスワードだけにしておきます。設定後、有効になっていることが確認できます。
ログイン機能の実装
Firebase本体の追加
Firebaseのスクリプトは、CDN, npm, Bower から好きな方法で取得してこれます。今回はCDNを利用します。
<script src="https://www.gstatic.com/firebasejs/4.10.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.10.1/firebase-auth.js"></script>
<script>
// Firebaseの初期化
// TODO: プロジェクトに合わせて各値を置き換えてください。
var config = {
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
};
firebase.initializeApp(config);
</script>
設定値は使用するサービスによっていろいろと設定する必要があるのですが、ここでは Authentication しか使わないので、apiKey と authDomain のみ設定します。上述のプロジェクトの設定を参照し、プロジェクトごとの設定値で置き換えて利用してください。
そのほかの機能もまとめて利用する場合
コンソールトップの「ウェブアプリに Firebase を追加」をクリックすると、全部入りの素にペットが表示されます。めんどくさかったらこれをまるっとコピペしても動きます。
Authentication だけ使うのであれば、上記の通り必要なものだけの方が無駄な読み込み時間等が削減できます。
FirebaseUIを読み込む
FirebaseUIをWebページに用意します。Firebase本体同様、CDN, npm, Bower から好きな方法で取得してこれます。ここでは CDN を使ってページ内に組み込みます。
<script src="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.css" />
FirebaseUIインスタンス初期化
FirebaseUIのインスタンスを初期化します。
var ui = new firebaseui.auth.AuthUI(firebase.auth());
FirebaseUIが描画されるDOM
FirebaseUIが描画されるHTML要素をあらかじめおいておきます。
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>
FirebaseUIの設定
サインイン成功時のコールバックや成功時のリダイレクト先URL等の設定を行います。
var uiConfig = {
callbacks: {
signInSuccess: function(currentUser, credential, redirectUrl) {
// サインイン成功時のコールバック関数
// 戻り値で自動的にリダイレクトするかどうかを指定
return true;
},
uiShown: function() {
// FirebaseUIウィジェット描画完了時のコールバック関数
// 読込中で表示しているローダー要素を消す
document.getElementById('loader').style.display = 'none';
}
},
// リダイレクトではなく、ポップアップでサインインフローを表示
signInFlow: 'popup',
signInSuccessUrl: '<url-to-redirect-to-on-success>',
signInOptions: [
// サポートするプロバイダ(メールアドレス)を指定
firebase.auth.EmailAuthProvider.PROVIDER_ID,
],
// Terms of service url.
tosUrl: '<your-tos-url>'
};
FirebaseUI描画
描画先の要素と、先ほど作成した設定情報を start
関数に渡すと、FirebaseUIが描画されます。
ui.start('#firebaseui-auth-container', uiConfig);
動作確認
ここまでで認証処理が完成です。上記コードをひとまとめにしたものを載せておきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>[firebase] my-sample-project</title>
<script src="https://www.gstatic.com/firebasejs/4.10.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.10.1/firebase-auth.js"></script>
<script src="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.css" />
<script>
// Firebaseの初期化
var config = {
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
};
firebase.initializeApp(config);
// FirebaseUIインスタンス初期化
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// FirebaseUIの各種設定
var uiConfig = {
callbacks: {
signInSuccess: function(currentUser, credential, redirectUrl) {
// サインイン成功時のコールバック関数
// 戻り値で自動的にリダイレクトするかどうかを指定
return true;
},
uiShown: function() {
// FirebaseUIウィジェット描画完了時のコールバック関数
// 読込中で表示しているローダー要素を消す
document.getElementById('loader').style.display = 'none';
}
},
// リダイレクトではなく、ポップアップでサインインフローを表示
signInFlow: 'popup',
signInSuccessUrl: '<url-to-redirect-to-on-success>',
signInOptions: [
// サポートするプロバイダ(メールアドレス)を指定
firebase.auth.EmailAuthProvider.PROVIDER_ID,
],
// Terms of service url.(サービス利用規約ページの)
tosUrl: '<your-tos-url>'
};
// FirebaseUI描画開始
ui.start('#firebaseui-auth-container', uiConfig);
</script>
</head>
<body>
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>
</body>
</html>
ブラウザで閲覧すると次のように表示されます。
未登録のメールアドレスを入力すると、アカウント作成のフォームが表示されます。
アカウントで登録すると、firebaseにユーザー情報が登録され、認証されます。
登録済のメールアドレスを入れると、パスワードの入力を求められます。
最後にコンソール画面から登録したアカウントが追加されていることを確認します。
以上でアカウント認証が完了です。
ログイン状態の確認
ログイン(サインイン)された状態かどうかを判定する必要があります。
例えば、サインインを完了後のリダイレクト先の画面で次のようにします。UI以外のスクリプトは同じように読み込んでおきます。
firebase.auth().onAuthStateChanged
関数で、認証状態の変化を監視します。認証されていれば user
オブジェクトに値が設定され、未認証であれば、null が設定されます。
var config = {
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
};
firebase.initializeApp(config);
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
console.log('auth user', user);
} else {
// No user is signed in.
}
});
メールアドレス存在確認
ログインの確認はできましたが、実際に登録されたメールアドレスが正しいものかどうか確認を行う必要があると思います。サインインしたユーザー情報のオブジェクトには、確認済のメールアドレスかどうかを判定するプロパティを保持しています。
firebase.auth().currentUser.sendEmailVerification()
で確認メールを送信可能です。
// 存在確認済のメールアドレスかどうか(true or false)
var verified = firebase.auth().currentUser.emailVerified;
console.log(verified);
// 未確認のメールアドレスの場合、メールを送信する
if (!verified) {
// メール送信処理
firebase.auth().currentUser.sendEmailVerification();
var email = firebase.auth().currentUser.email;
console.log('確認メールを送信しました。', email);
}
メールテンプレートはコンソール画面の設定から編集可能です。確認メールのリンクをクリックすると、メールアドレスの確認が行われます。
実装については以上です。
注意点
動作の確認はローカルファイルを直に見る方法(file:///C:/…みたいな感じ)ではうまく動かないので、開発用のサーバーを立てなければいけません。
コンソール画面の [Authentication] -> ログイン方法 から 承認済ドメイン を確認・設定ができます。デフォルトだと localhost と xxx.firebase.app になっています。ここで設定されたドメインからしかログインできませんので注意しましょう。
独自のUIで認証を行う場合
上記の別記事にまとめました。FirebaseUIを使わない方法です。
雑感
非常に便利なサービスです。認証周りの実装がまるっと置き換えられるので、ユーザー情報の管理など面倒事から解放されます。
認証以外にもデータ管理などいろいろな機能がありますが、認証処理だけでもとても便利だと感じました。
以上です。
コメントを書く