Web

ViteのReactを使ってFirebase フェデレーションIDプロバイダのログイン処理について解説

2022年3月13日

フェデレーションプロバイダを使ったログイン処理

GoogleアカウントやFacebookアカウントなどを利用したログイン処理を作成するのは、Firebaseを利用するとカンタンに実装することができます。

この記事では、ViteのReactを使ったプロバイダのログイン方法を解説しています。

create-react-appコマンドオプションで作成されたReactとは環境変数などの読み込みなど若干違うので、create-react-appでReactを作成した方は、参考程度にご覧ください。

フェデレーションとは

フェデレーションとは

Firebaseのドキュメントでは、フェデレーションIDプロバイダについてGoogleログインやFacebookログインなどと明記しています。

フェデレーションってなんなのか?と知らなかったので調べてみました。

ITの意味合いだと、サービス間のユーザ認証を連携する意味があるようです。

Firebaseのログイン認証で例えると、「Firebaseを使うことでサービス間の認証処理を共有できる」が意味合い的に近いのかなと思います。

Firebaseで利用できるフェデレーションIDプロバイダの種類

Firebaseで利用できるフェデレーションの種類

Firebaseで利用できるフェデレーションIDのプロバイダは下記の画像の通り使えます。

主要なプロバイダのGoogleをはじめ、FacebookやApple、TwitterやYahooなどもあります。

ですが、GAFA(GAMA?)でもお馴染みのAmazonが無いのにはビックリです。

フェデレーションプロバイダの種類

フェデレーションプロバイダの追加の方法

Firebaseのフェデレーションプロバイダの追加

フェデレーションプロバイダの追加方法はとてもカンタンです。

まずは、左メニューの「Authentication」をクリックします。

すると、Usersの画面が表示されるので、上のタブにある「Sign-in method」をクリックします。

左メニューからAuthenticationを選択

1つも追加されていなければ、下記の様な画面は表示されません。

メールとパスワードについては、ログイン画面を作成した記事の中で解説しています。

興味があればご覧ください。

それでは、赤枠の「新しいプロバイダを追加」をクリックします。

プロバイダの追加

下記の様に、「ネイティブのプロバイダ」と「追加のプロバイダ」が表示されます。

追加しているとチェックされて灰色表示されます。

赤枠の通り、Googleのプロバイダを選択します。

Googleを選択

選択すると下記の画面が表示されます。

最初は有効になっていたので、トグルボタンを有効にします。

プロバイダを有効化

有効にするとプロジェクト名が自動的に入った下記の画面が表示されます。

サポートメールが必須になっており、選択されていない状態だったのでメールアドレスを選択します。

保存ボタンをクリックすとプロバイダが追加されます。

プロジェクトとメールの選択

成功するとプロバイダ一覧にGoogleが表示されます。

プロバイダ一覧

Googleのログインを実装

Googleログインの実装

Googleログインを実装するには、公式の開発サイトよりボタンをダウンロードします。

自分で作成したログインボタンにしたいって人は、ダウンロードしないで作ってみてください。

ただし、必ずガイドラインを読む様にしましょう!

GoogleアイコンだけによるログインやGの部分のダークバージョンやライトバージョンによる使用禁止、他にもGの部分のアイコンの背景は白といったルールがあります(一部抜粋で他にもある)

そんな感じで、いろいろ見てたらガイドライン違反しているサービスサイトがちらほら見受けられたので、注意してください。

ダウンロードも完了していたら、実際に実装の方を進めます。

前回作成した、ログイン画面とFirebaseの認証関連をそのまま利用するので、前回の記事を見てないよって方はご確認ください。

GoogleAuthProviderを利用する

前回の記事のソースコードからゴリゴリ変更しましたが、重要な部分だけピックアップして解説します。

import './Login.css'
import {useState} from "react";
import {auth} from "./Firebase";
import googleSignInButton from './img/btn-google.png';
import {GoogleAuthProvider} from 'firebase/auth';

const Login = (props) => {
    const styleRoot = 'Login container md:3/5 lg:w-3/6 xl:w-2/5 ';
    const styleHeader = 'h-20 flex justify-center items-center text-3xl';
    const styleMain = 'border border-emerald-400 p-5 rounded-md';
    const styleRow = 'p-5 flex flow-root';
    const styleInputLabel = 'block pb-1 text-lg text-emerald-700';
    const styleInput = 'border rounded-md border-emerald-500 w-full p-2 text-lg text-emerald-900';
    const styleBtn = 'p-2 w-full rounded-lg bg-emerald-400 hover:opacity-80 action:opacity-50 ' +
        'text-teal-50 text-lg hover:border-emerald-500 hover:ring-2 font-black';
    const styleProviderBtn = 'w-full flex justify-center';

    const formsInit = {
        email: '',
        password: '',
    };

    const [forms, setForms] = useState(formsInit);
    const handleEmailChange = e => setForms({...forms, email: e.target.value});
    const handlePasswordChange = e => setForms({...forms, password: e.target.value});
    const handlePasswordReminder = e => {
        console.log('パスワードリマインダー');
        e.preventDefault();
    };

    const clickForms = e => {
        e.preventDefault();
        auth.signInWithEmailAndPassword(forms.email, forms.password)
            .then(r => {
                console.log('パスワード成功', r);
            }).catch(e => {
                console.log('パスワードエラー', e);
            });
        console.log('buttonが押されました');
    };

    const clickGoogleAuth = e => {
        let provider = new GoogleAuthProvider();
        auth.signInWithPopup(provider).then(result => {
           console.log('Google認証成功', result);
        }).catch(error => {
            console.log('Google認証失敗', error);
        });
    };

    // 認証チェック処理
    auth.onAuthStateChanged(user => {
        console.log('認証チェック', user);
    });

    return (
        <div className={styleRoot}>
            <header className={styleHeader}>
                <h1 className="text-center">ログイン画面</h1>
            </header>
            <main className={styleMain}>
                <form onSubmit={clickForms}>
                    <div className={styleRow}>
                        <label htmlFor="email" className={styleInputLabel}>メールアドレス</label>
                        <input id="email" className={styleInput} name="email"
                               type="email" autoComplete="email" required
                               value={forms.email} onChange={handleEmailChange}/>
                    </div>
                    <div className={styleRow}>
                        <label htmlFor="password" className={styleInputLabel}>パスワード</label>
                        <input id="password" className={styleInput} name="password"
                               type="password" autoComplete="current-password" required
                               value={forms.password} onChange={handlePasswordChange}/>
                    </div>
                    <div className={styleRow}>
                        <div>
                            <a href="#" onClick={handlePasswordReminder}>パスワードを忘れた方</a>
                        </div>
                    </div>
                    <div className={styleRow}>
                        <button type="submit" className={styleBtn}>ログイン</button>
                    </div>
                </form>
                <div className={styleRow}>
                    <div className="flex items-center">
                        <hr className="w-full" />
                        <span className="w-1/2 text-center">または</span>
                        <hr className="w-full" />
                    </div>
                </div>
                <div className={styleRow}>
                    <button type="button" className={styleProviderBtn} onClick={clickGoogleAuth}>
                        <img src={googleSignInButton} className="h-14" />
                    </button>
                </div>
            </main>
        </div>
    );
}

export default Login;

まずはダウンロードしたボタンについて説明します。

このLoginファイルは、srcの直下にあります。

その為、srcの中にimgディレクトリ作成して、「btn-button.png」ファイル名を変更してダウンロードしたログインボタンを入れています。

ちなみに、ダウンロードしたボタンは1xや2x、vectorといった形で分かれており、好みで選択してください。

Googleボタン

その画像ファイルを静的ファイルとして読み込む為に、importしているのがgoogleSignInButtonの部分になります。

import googleSignInButton from './img/btn-google.png';

次に、Google認証を行う為に「GoogleAuthProvider」をインポートします。

import {GoogleAuthProvider} from 'firebase/auth';

あとは利用する為に、無名関数を使って変数化しておきます。

const clickGoogleAuth = e => {
    let provider = new GoogleAuthProvider();
    auth.signInWithPopup(provider).then(result => {
       console.log('Google認証成功', result);
    }).catch(error => {
        console.log('Google認証失敗', error);
    });
};

プロバイダを定義して、auth.signInWithPopupで定義したプロバイダを入れます。

これだけで、Google認証のポップアップ画面が表示されます。

ですが、これだけだと動かないのので、下記の様にclickイベントを利用してclickGoogleAuthを発火させます。

ちなみにclickイベントはonClickの部分になります。

<button type="button" className={styleProviderBtn} onClick={clickGoogleAuth}>
    <img src={googleSignInButton} className="h-14" />
</button>

ログイン画面を確認するとこの様な感じになります。

ログイン画面

「Sign in with Google」のボタンをクリックすると下記の画面が表示されます。

Googleログイン画面

ログイン認証が成功すると下記のuser部分の値が返ってきます。

ちなみに、失敗したり認証していない状態だと、戻り値としてnullが返ってきます。

auth.onAuthStateChanged(user => {
    console.log('認証チェック', user);
});

Facebookのログイン認証を実装

Facebookプロバイダの実装

Facebookもロゴのついてガイドラインがありました。

公式にあるここからロゴをダウンロードできるようです。

しかしGoogleの様にログインボタンが準備されているわけではないため、新たに作成する必要があります。

もしくは、公式にあるコードを利用するかです。

FacebookもGoogleとほとんど似た様な感じの実装になります。

初めにFacebookのプロバイダを利用する為に、Firebaseコンソールで有効処理をします。

次に認証処理を実行する為に、FacebookAuthProviderを実装します。

Facebookプロバイダの登録

Googleの登録とほとんど同じなのですが、Googleと違ってFacebookでアプリIDとアプリシークレットを取得する必要があります。

この2つを取得することでFacebookを利用した認証処理を行うことができます。

Facebookプロバイダの設定

アプリIDを取得する為に、Meta for Developersから登録を行います。

登録方法はFacebook Developersの「Facebook開発者として登録する」のページを参考にしました。

まず、Meta for Developersにアクセスして、右上の「スタート」をクリックします。

Facebook devlopers登録開始

クリックしたら、ようこそ画面が出るので「次へ」をクリックします。

Facebook for Developersのようこそ画面

次に電話番号を利用してアカウントの認証をする必要があります。

Facebook 電話番号によるアカウントの認証

次にメールアドレスの確認になります。

開発ニュースなどの最新の情報が必要であれば、チェックを入れて「メールアドレスを認証」をクリックします。

メールアドレス認証

最後は、自分がもっと当てはまるものはどれかを選択する必要があります。

選択すると「登録完了」がクリックできる様になります。

経験の選択

完了すると下記の様にアプリ作成画面が表示されます。

アプリ作成画面

「アプリを作成」をクリックすると、下記の様にアプリタイプを選択する画面が表示されます。

自分がどういったアプリを作成するのか選択します。

アプリタイプの選択

選択して「次へ」をクリックすると、アプリの基本情報を入力する画面が表示されます。

アプリの表示名と、アプリの連絡先、ビジネスアカウントの選択に関しては任意になります。

アプリの基本情報の入力

表示名を入力したら、「アプリを作成」のボタンがクリックできる様になります。

クリックしたらセキュリティの為にパスワードを入れる必要があります。

パスワード再確認

完了すると、ダッシュボード画面が表示されるので左メニューから設定ー>ベーシックをクリックしていきます。

下記の様にアプリIDとapp secretが表示されるので、FirebaseのFacebookプロバイダの登録画面に入力して有効化します。

有効化に成功すると下記のようにFacebookが有効化表示されます。

FacebookAuthProviderを利用する

Facebookの有効化ができたのでGoogleの時と同じ様に画像とFacebookAuthProviderのインポート処理を行います。

import facebookSignInButton from './img/btn-facebook.png';
import {GoogleAuthProvider, FacebookAuthProvider} from 'firebase/auth';

FacebookAuthProviderはGoogleAuthProviderとモジュール先のパスが同じなので、カンマで区切って追加します。

次にFacebookの認証ボタンがクリックされた時の処理をします。

const clickFacebookAuth = e => {
    let provider = new FacebookAuthProvider();
    auth.signInWithPopup(provider).then(result => {
        console.log('Facebook認証成功', result);
    }).catch(error => {
        console.log('facebook認証失敗', error);
    });
};

この部分とか改良余地が有りまくりで、providerの部分以外はGoogleの認証と同じなのでコールバックなりプロバイダの引数を設定するなりでコンパクトにできるが、今回は放置します。

あとは、先ほど作成したFacebookのイベント処理をonClickに登録するだけです。

<div className={styleRow}>
    <button type="button" className={styleProviderBtn} onClick={clickFacebookAuth}>
        <img src={facebookSignInButton} className="h-14" />
    </button>
</div>

Facebookプロバイダの有効化に成功しているので確認してみます。

下記の様に「URLを読み込めません」と失敗ページが表示されました。

ドメインの設定をしていないのが理由だったので、Facebookで全てのドメインを設定します。

設定失敗ページ

左メニューのFacebookログインの設定をクリックします。

Facebookログイン設定

クライアントOAuth設定画面が表示されます。

下記の有効なリダイレクトURIに適切な値を設定する事で、URLが読み込めないエラーを解消する事ができます。

リダイレクトUIRの設定

ではこの適切なURIの値はどこにあるのか?

それは、Firebaseのプロバイダを有効化したFacebookの画面にあります。

赤枠の部分をURIの値になります。

FacebookリダイレクトURI

まとめ

Firebaseを使えば、Googleログインはカンタンに実装する事ができます。

Googleの場合はカンタンだったのですが、Facebookについては、アプリIDやらApp Secretなどがあり、リダイレクトURIの設定が必要なります。

Farebaseのドキュメントをしっかりと読んで、ある程度の知識があればカンタンなのかもしれませんが、そのドキュメントに書かれている事が若干違うので少しハマった感じになります。

GoogleとFacebookのログインで長くなったので、次回以降に他のプロバイダも試していきます。

Udemyへ

今後の人生を豊かにする為にキャリアアップのステップとして、自分への投資をしてみませんか?

-Web
-, ,