Firebaseによるユーザー認証機能を実装する

はじめに

本記事ではFirebaseを使用したユーザー認証機能の実装を行います。言語はTypescriptを使用していきます。

そもそもFirebaseってどういうものか、よくあるメールアドレスとパスワードによるユーザー認証機能を提供しつつ、データベースとしての役割を果たすサービス、というザックリとした理解です。(現状)

そんなの、使ってみればわかるじゃないですか!やっていきましょう!

実施した内容

Firebaseのプロジェクト作成

Firebaseのページからプロジェクトの作成を行っていきます。無料プランがあって良かった。。

プロジェクトを作成していきます。

プロジェクト名を入力します。

特にアナリティクス機能は不要と考えたので今回はアナリティクスを無効にしたまま進めます。

プロジェクトを作成ボタンを押してしばらく待つと…

完成しました。料金プランは無料のSparkのままで…。

これでFirebaseのプロジェクト作成が終わりました。次は初期設定です。

Firebaseの初期設定

Firebaseのアプリの設定を行っていくため、プロジェクトの設定ページに移動します。

Webアプリケーションを作成するので、今回はこちらを選択します。

ニックネームを付けてアプリを登録します。Firebase Hostingについて、この時点ではまだ利用するか決めかねたので、そのままにしています。。。が、調べてみて少し使ってみたくなりました。

アプリを登録した後に表示される firebaseConfigはユーザー認証の際に必要となります。

ここまででFirebase側の初期設定は完了です。

ユーザーの登録

アプリにアクセス可能なユーザーの登録を行います。コードで書いてあげるのがスマートなのでしょうが、今のところ身内以外で使う予定がないので、今回は手動で登録してきます。

始めるをクリックします。

認証はメールとパスワード方式とします。

メールリンクでのログインは許可しないので、上のボタンだけ有効にしておきます。

ここまででメールアドレス・パスワードによるユーザー認証が有効になっていますので、ユーザーを追加していきます。

使用したいメールアドレスとパスワードを入力して、ユーザーを追加します。

これでユーザーの登録も完了です。

ログインフォームの作成

ログインのページ作成はMUIのTemplateページのものを利用しています。

https://mui.com/material-ui/getting-started/templates/sign-in

ソースコードもgithubに開示されていますので、そちらから。

そのままでは入力したパスワードが見えてしまうので、パスワードの入力欄はFormControlを使って以下のように変更しました。

            <FormControl variant="outlined" required fullWidth>
              <InputLabel htmlFor="outlined-adornment-password">Password</InputLabel>
              <OutlinedInput
              name="password"
              label="Password"
              type={showPassword ? 'text' : 'password'}
              id="outlined-adornment-password"
              endAdornment={
                <InputAdornment position="end">
                  <IconButton
                    aria-label="toggle password visibility"
                    onClick={handleClickShowPassword}
                    onMouseDown={handleMouseDownPassword}
                    edge="end"
                    >
                    {showPassword ? <VisibilityOff /> : <Visibility />}
                  </IconButton>
                </InputAdornment>
              }
              />
            </FormControl>

その他、パスワードの再設定等は行える必要がないので一旦コメントアウトし、最終系は以下のようになりました。

SIGN INクリック時のコード作成

SIGN INボタンをクリックしたら走るコードの部分にFirebaseのEmail・パスワード認証のためのコードを挿入します。

正しくユーザー認証が行われればbookmarkページに画面が遷移し、認証失敗の場合には何も起きないコードとなっています。…ここはポップアップなりで注意すべきですね。

  const handleSubmit = async(event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const data = new FormData(event.currentTarget);
    const email = String(data.get('email'));
    const password = String(data.get('password'));

    try {
      await signInWithEmailAndPassword(auth, email, password);
      console.log("Login Success.");
      router.push('/bookmark');
    } catch (error) {
      console.log("Login Failed.");
      console.log(error);
    }

  };

ここでauthの情報は/lib/FirebaseConfig.tsというファイルを以下のように作成し、そこから取得するようにしています。こちらではFirebaseの認証を行うためのコードが入っています。

import { initializeApp, getApps } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_APIKEY,
  authDomain: process.env.NEXT_PUBLIC_AUTHDOMAIN,
  projectId: process.env.NEXT_PUBLIC_PROJECTID,
  storageBucket: process.env.NEXT_PUBLIC_STORAGEBUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_MESSAGINGSENDERID,
  appId: process.env.NEXT_PUBLIC_APPID
};

if (!getApps()?.length) {
  initializeApp(firebaseConfig);
}

export const auth = getAuth();
export const db = getFirestore();

FirebaseのKey情報については直接コードの中に埋め込むことはせず、.env.localファイルの中に書き込むようにします。間違ってgithubにKey情報を上げないために、ですね。

動作の確認

適当なユーザー名とパスワードを入力してSIGN INを押した場合には何も起こりません。(何も起こらないのも問題ですが…)

デバッグのコンソール上ではFirebaseの認証に失敗しているメッセージが表示されています。

先ほどFirebase上に作成したユーザーでログインした場合には、無事、別のページに遷移することが出来ました。

無事、Firebaseによるユーザー・パスワード認証の機能の実装まで出来ましたので、今回の記事はここまでとします。

さいごに

難しい。本当に難しい。。

Web上に色んなサンプルコードを置いてくれている偉人達の助けを借りながら形だけは何とか作成出来ました。Next.jsのverion.14で書いてくれている人はまだまだ少ないですね。。

次回はログインした状態・セッションを維持するためのコード追加を行います。

ではまた。