Firebaseの技術情報サイト

Firebaseの技術情報サイト

Firebase活用の為の技術情報サイトです

Firebaseのログイン機能の使いかた

Firebaseのログイン機能の使いかた

Firebaseがサポートするログイン(ユーザー認証機能)はとても強力です。 その中から、一番多く利用されているであろう「E-Mailとパスワードによる認証」について解説します。

シンプルな機能

E-Mailとパスワードによる認証とは、ユーザー名としてE-Mailアドレスを使って、パスワードを利用してFirebaseのプロジェクトにログインする方法です。

E-Mailアドレスは、世界に1つだけしかない事が保証されているのでユーザー名として使うのに都合が良い物の一つです。このユーザー名とパスワードの称号や、ユーザー名パスワードの管理もFirebase側でやってくれます。

ユーザーの登録はどうするのか?

ユーザーの登録は2つのやり方がFirebaseではサポートされています。

  • Firebaseコンソールもしくは、Admin SDKを利用して管理者が作成する
  • 利用者本人が作成する

管理者が作成する場合は余り問題はなく、Firebaseコンソールで作成して利用者に仮のパスワードを伝えるという方法になります。Admin SDKを使って管理用のアプリを開発して、利用者の管理をすることも可能です。

利用者本人がアカウントを自分で作成する場合、その仕組みはWebアプリ(Webサービス)側で作る必要があります。登録の為のフォームを作って、送信する仕組みを作れば良いだけなので簡単です。

フォームで、E-Mailアドレスとパスワードを入力してもらってそれを、Firebase側に送れば良い事になります。必要に応じて他の情報も一緒に入力してもらう事も可能ですが、Firebase側で必要なのはこの2つの情報だけです。

firebase.auth().
    createUserWithEmailAndPassword(email, password).
    catch((error) => {
        // 作成の処理でエラーが発生した場合の処理
})

ゆざーの作成はこれだけです。シンプルですよね!

E-Mailアドレス使用の問題点

唯一ある問題は、他人のE-Mailアドレスを使ってログインアカウントを作る事も可能であるという事です。登録時にはそのE-Mailアドレスが利用者本人の物かどうかを確認する事は普通はできません。

そのため、対策としては登録後、E-Mailの所有権を確認するためのE-Mailを登録したE-Mailアドレスに送って、そのリンクをクリックしてもらう事で、E-Mailの所有権を確認する事ができます。この機能もFirebaseはサポートしています。

その場合は、先ほどの処理に追加で確認にメールを送る処理が必要になります。

firebase.auth().
    createUserWithEmailAndPassword(email, password).
    then((user) => {
        // アカウントの作成が成功
        const currentUser = firebase.auth().currentUser;
        currentUser.sendEmailVerification().then(() => {
            // 確認のE-Mail送信に成功
            // この時点ではE-Mailアドレスの所有権が
            // 確認されていないため、強制的にサインアウトします。
            // (サービスの利用はできない)
            firebase.auth().signOut()
        }).catch((error) => {
            // 確認のE-Mail送信でエラー(エラー処理)
        })
    }).
    catch((error) => {
        // 作成の処理でエラー(エラー処理)
})

「createUserWithEmailAndPassword()」でアカウント作成に成功した場合は、そのアカウントでログイン状態になります。E-Mailの所有権が確認されるまで、サービスの利用を認めない場合は、強制的にサインアウトする必要があります。(利用を認める場合はそのままで問題ありません)

送られるE-Mailの内容は?

Firebaseコンソールのユーザー認証(Authentication)の設定の中に「テンプレート」があるのでここで設定できます。

ユーザー認証関連で設定できるのは

  • メールアドレスの確認
  • パスワードの再設定
  • メールアドレスの変更

このE-MailはFirebase側で送ってくれますが、自分のメールサーバーの設定をすれば、自分のメール(SMTPサーバー)を使って発送する事も可能です。メッセージの中身も自由に設定できます。

ログインの処理は?

ログインの処理もE-Mailの所有権の確認を利用の条件にする場合は注意が必要です。アカウント作成時点で強制サインアウトしても、再ログインした場合は、ログイン自体は可能だからです。

firebase.auth().
    signInWithEmailAndPassword(email, password).
    then((usr) => {
        const currentUser = firebase.auth().currentUser;
        // E-Mailの確認が取れていない場合は強制サインアウト
        if (!currentUser.emailVerified) {
            firebase.auth().signOut()
        }
})

これで一通りの処理は可能です。

パスワードを忘れた場合の処理は?

利用者がパスワードを忘れてしまった場合も想定されます。 その場合は、パスワードを再設定する為のE-Mailを送ります。

firebase.auth().sendPasswordResetEmail(email).then(() => {
    // 再設定のE-Mailの送信成功
}).catch((error) => {
    // 再設定のE-Mailの送信処理中にエラー
})

パスワードの再設定は基本的にE-Mailを送って行います。 こうした一連の処理を考えると、利用者自身がアカウントの登録をする場合はE-Mailの所有権を確認した方が運用上良い事になります。

セッションの管理

利用者から見ると、ページを開ける度にログインするのは不便な場合もあります。Firebaseでは、アプリによって、再ログインをしないで利用するための設定も幾つか用意されています。

Webサイトで利用の場合は

  • 同じドメインから利用している場合は、再ログインをしなくても利用可能
  • 同じセッション(同じブラウザーのタグ)を利用している場合は利用可能
  • 毎回ログイン(再読み込み時も)

もちろんブラウザー側でアクセス履歴をクリアした場合は再ログインが必要です。(セッションとクッキーを利用しているため)

この設定は、アプリの初期化の時に

firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)

を実行すると設定できます。SESSIONの部分を変えれば好きな設定にできます。

設定
LOCAL 同じドメインの場合再ログインは不要
SESSION 同じセッション・タブを利用の場合は不要
NONE 毎回ログインが必要

もちろん、アプリの初期化時に、以前のログイン状態の確認をする必要があります。以下のコードで、ログイン状態の管理が可能です。

firebase.auth().onAuthStateChanged((user) => {
    if (user) {
        // ログイン状態
    } else {
        // ログインしていない状態
    }
})

ReactやVueを使う場合は、これを利用してログイン状態のステートを変えてあげれば、画面を切り替える事ができます。これは、利用者が意図的にサインアウトした場合もイベントとして検出できるのでこれを利用すると、アプリ内でのログイン状態を管理できます。

Typescriptで書くと理解が早まる!

以上がFirebaseのログイン機能の基本的な使いかたです。 読んでいるだけだと簡単そうですが、実は使い始めるとアレ!?というのがある場合もあります。混乱しやすいのが

firebase.auth().signInWithEmailAndPassword(email, password).
    then((usr) => {
        const currentUser = firebase.auth().currentUser();
        if (!currentUser.emailVerified) {
            firebase.auth().signOut();
        }
    });

のコードです。「user」と「currentUser」が出てきますよね?

このコードをTypescriptで書くと

firebase.auth().
    signInWithEmailAndPassword(email:string, password:string).
    then((usr:firebase.auth.UserCredential) => {
        const currentUser:firebase.User|null = firebase.auth().currentUser;
        if (currentUser && !currentUser.emailVerified) {
            firebase.auth().signOut();
        }
    });

の様に型を明確にできます。実は、「signInWithEmailAndPassword()」の戻り値は、「firebase.auth.UserCredential」という型で、「emailVerified」という情報は入っていないのです。そのために、別に「currentUser」を取得してチェックしないといけないというわけです。さらに、「firebase.auth().currentUser」は「null」の可能性もあるので、使う前にチェックする必要があります。

記述が面倒になりますが、コードの信頼性は大きく向上します。

まとめ

Firebaseのログイン(ユーザー認証)機能のうち、「E-Mailアドレスとパスワード」を利用した物を使って実際に実装するための基本的な使いかたを解説しました。

ポイントは

  • 利用者自身の登録を認めるか、認める場合は以下の項目も検討
  • E-Mailの所有権を確認するか(確認した方が運用上は良い)
  • E-Mailの所有権の確認の前の利用を容認するか

さらに、セッションやクッキーによる再ログインの必要性も検討する必要があります。それぞれはシンプルですが、WebアプリやWebサービスとしてまとめるためには検討する事ややる事も意外にあるものです。

それでも、Firebaseを利用すれば、ログイン機能を最初から作る事を考えると作業量は劇的に少なくてすみます。