🔰基礎技術

ログイン機能は「Firebase Auth」に丸投げでOK|Next.jsでの実装手順とセキュリティの仕組み

個人開発でアプリを作る時、避けて通れないのが「ログイン機能(ユーザー認証)」です。

しかし、これを「勉強のために」と自分で作ろうとするのは、手製の金庫にお金を預けるようなものです。
どんなに頑丈に作ったつもりでも、プロの泥棒(ハッカー)から見れば穴だらけです。

今回は、Googleが提供する「Firebase Authentication(オーセンティケーション)」を使って、安全かつ爆速でログイン機能を実装する方法を解説します。

1. Firebase Authenticationとは?

一言で言うと、「会員証の発行と確認を全自動でやってくれる受付システム」です。

アプリの入り口に設置するだけで、以下の認証方式に対応できます。

  • ソーシャルログイン: Google、X(Twitter)、GitHub、Apple、Facebookなど
  • 従来の方法: メールアドレス & パスワード
  • 最新の方法: 電話番号認証(SMS)、パスワードレス認証

これらが、管理画面のスイッチをオンにするだけで使えるようになります。

2. なぜ「自作」してはいけないのか?

「ユーザーIDとパスワードをデータベースに保存するだけでしょ?」と思った方は要注意です。
Firebaseを使うべき理由は、主にセキュリティ(暗号化)の壁があるからです。

🚫 自作した場合のリスク

  • パスワードの保管:
    データベースにパスワードをそのまま保存(平文保存)するのは犯罪級の御法度です。
    通常は「ハッシュ化(ぐちゃぐちゃの文字列に変換)」し、さらに「ソルト(味付け)」という技術で復元不可能にする必要があります。これをミスると即・情報漏洩です。
  • セッション管理:
    「ログイン中であること」を証明するチケット(トークン)の有効期限や、偽造防止の仕組みを作るのは非常に高度な知識が必要です。

✅ Firebaseに任せると…

これらの面倒で責任重大な処理を、Googleのセキュリティチームが24時間体制で管理しているシステムに丸投げできます。
個人開発者が、これを使わない手はありません。

3. 類似サービス(Auth0 / Clerk)との違いは?

認証サービス(IDaaS)はFirebase以外にもあります。特に有名なのが Auth0(オースゼロ)Clerk(クラーク) です。
「どれを選べばいいの?」と迷う初心者のために、比較表を作りました。

サービス名特徴初心者おすすめ度
Firebase AuthGoogle純正。DB(Firestore)との連携が最強。◎(優勝)
ClerkNext.js専用と言えるほど相性が良い。UIを作る必要がない。◯(英語のみ)
Auth0大企業向け。機能は多いが設定が複雑。△(難しい)

🔰 なぜ初心者に「Firebase」推しなのか?

理由は3つあります。

  1. データベース(Firestore)との連携が「自動」だから
    これが最大の理由です。Firebaseを使えば「ログインした本人だけが自分のデータを読み書きできる」という設定(セキュリティルール)を、追加コードなしで簡単に書けます。他社サービスだと、ここを繋ぐのが少し大変です。
  2. 日本語の情報量が圧倒的だから
    歴史が長くユーザー数が多いため、エラーが出ても日本語で検索すればすぐに答えが見つかります。Clerkなどはまだ英語情報が中心です。
  3. 無料で使える範囲が広いから
    個人開発レベルであれば、実質無制限に近い感覚で無料で使い倒せます。

4. 【準備】Firebase側での設定手順

では、実装に入りましょう。まずはFirebaseの管理画面(コンソール)にログインして利用できる状態に設定します。
※前回の記事でプロジェクト作成までは完了している前提です。

Step 1: Authenticationを有効にする

  1. Firebaseコンソールの左メニューから「Authentication」をクリック。
  2. 「始める」ボタンをクリック。

Step 2: ログイン方法を選ぶ(今回はGoogle認証)

今回は最も簡単でユーザー体験が良い「Googleログイン」を設定します。

  1. 「ログインプロバイダ」のタブで「Google」を選択。
  2. 右上のスイッチを「有効」にする。
  3. プロジェクトのサポートメール(自分のGmail)を選択し、「保存」をクリック。

これで裏側の準備は完了です!

5. 【実装】Next.jsでログインボタンを作る

ここからはVS Codeでの作業です。
「メモアプリ」の入り口として、ログインボタンを設置してみましょう。

① 必要なツールを入れる

ターミナルで以下のコマンドを実行し、Firebaseを扱えるようにします。

npm install firebase

①-2. 【重要】「鍵」を環境変数ファイルにセットする

Firebaseを動かすための「APIキー」を、プロジェクトに登録します。
直接コードに書くと危険なので、「.env.local」という専用のファイルを使います。

手順:

  1. VS Codeのプロジェクトの一番上の階層(package.jsonがある場所)に、.env.local という名前でファイルを新規作成します。
  2. Firebaseコンソールの「プロジェクトの設定(歯車アイコン)」→「全般タブ/マイアプリ(下の方)」にある const firebaseConfig = { ... } の中身を見ながら、以下のように書き込みます。
# .env.local
# ="..." の右側に、Firebaseコンソールの値をコピペしてください
NEXT_PUBLIC_FIREBASE_API_KEY="AIzaSyD..."
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN="your-project.firebaseapp.com"
NEXT_PUBLIC_FIREBASE_PROJECT_ID="your-project-id"
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET="your-project.appspot.com"
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID="123456789"
NEXT_PUBLIC_FIREBASE_APP_ID="1:12345:web:..."

⚠️ 設定後の注意:サーバーを再起動しよう

.env.local ファイルを作ったり書き換えたりした後は、一度開発サーバーを停止し、再起動しないと読み込まれません。

【停止コマンド】
Windows: Ctrl + C
Mac: Control + C

※Macの方へ:コピーなどで使う Command ではなく Control キーですのでご注意ください。

停止後、再度 npm run dev を実行してください。

② 接続設定ファイルを作る

lib フォルダの中に firebase.ts を作成します。
※キーはFirebaseコンソールの「プロジェクトの設定(歯車アイコン)」→「全般タブ/マイアプリ」から確認できます。

// lib/firebase.ts

import { initializeApp } from"firebase/app";
import { getAuth } from"firebase/auth";

// 環境変数で設定したキーの読み込み
const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID
};

// Firebaseアプリの初期化
const app = initializeApp(firebaseConfig);
// 認証機能をエクスポートして他で使えるようにする
export const auth = getAuth(app);

③ ログイン/ログアウトボタンを作る

app/components/ フォルダに AuthButton.tsx を作成します。
これが「ログイン状態」を監視し、ボタンを出し分ける部品になります。

// app/components/AuthButton.tsx
"use client"; // ユーザー操作があるのでClient Componentにします

import { signInWithPopup, GoogleAuthProvider, signOut } from"firebase/auth";
import { auth } from"@/lib/firebase";
import { useState, useEffect } from"react";

export default function AuthButton() {
// ログインしているユーザー情報を保持する箱
const [user, setUser] = useState<any>(null);

// 画面が開かれたら「監視」を開始する
  useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((currentUser) => {
      setUser(currentUser); // ログイン状態が変わったら箱の中身を更新
    });
return () => unsubscribe(); // 画面を閉じる時に監視を終わる
  }, []);

// ログイン処理
const handleLogin = async () => {
const provider = new GoogleAuthProvider();
await signInWithPopup(auth, provider);
  };

// ログアウト処理
const handleLogout = async () => {
await signOut(auth);
  };

return (
    <div>
      {user ? (
// ログインしている時の表示
        <div>
          <p>ようこそ、{user.displayName}さん</p>
          <button onClick={handleLogout} style={{ padding: "10px", background: "#ccc" }}>
            ログアウト
          </button>
        </div>
      ) : (
// ログインしていない時の表示
        <button onClick={handleLogin} style={{ padding: "10px", background: "#4285F4", color: "white" }}>
          Googleでログイン
        </button>
      )}
    </div>
  );
}

④ トップページに配置する

最後に、app/page.tsx(トップページ)にこのボタンを置きます。
以前作成した「お問い合わせ」へのリンクも残しておきましょう。

// app/page.tsx
import Link from"next/link";
import AuthButton from"./components/AuthButton";

export default function Home() {
return (
    <main style={{ padding: "50px", textAlign: "center" }}>
      <h1>Simple Memo App</h1>
      <p>個人開発のためのデモアプリです</p>

      <div style={{ margin: "30px 0" }}>
        <h2>ログインはこちら</h2>
        <AuthButton />
      </div>

      <hr />

      <div style={{ marginTop: "20px" }}>
        <Link href="/contact" style={{ color: "blue", textDecoration: "underline" }}>
          お問い合わせフォームへ
        </Link>
      </div>
    </main>
  );
}

まとめ:これで「誰が」来たか分かるようになった

お疲れ様でした!ブラウザで確認して「Googleでログイン」ボタンを押し、自分の名前が表示されれば成功です。

たったこれだけのコードで、「安全なユーザー管理機能」が手に入りました。
ユーザーが特定できたということは、次は「そのユーザーだけの専用ノート(データ)」を作ることができます。

次回は、いよいよデータベース「Firestore」を使って、ログインした人だけが読み書きできるメモ機能を実装します。

👉 次のステップ:[次回記事:Firestore入門。ログインユーザーだけのデータを保存・表示する方法]

-🔰基礎技術