個人開発でアプリを作る時、避けて通れないのが「ログイン機能(ユーザー認証)」です。
しかし、これを「勉強のために」と自分で作ろうとするのは、手製の金庫にお金を預けるようなものです。
どんなに頑丈に作ったつもりでも、プロの泥棒(ハッカー)から見れば穴だらけです。
今回は、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 Auth | Google純正。DB(Firestore)との連携が最強。 | ◎(優勝) |
| Clerk | Next.js専用と言えるほど相性が良い。UIを作る必要がない。 | ◯(英語のみ) |
| Auth0 | 大企業向け。機能は多いが設定が複雑。 | △(難しい) |
🔰 なぜ初心者に「Firebase」推しなのか?
理由は3つあります。
- データベース(Firestore)との連携が「自動」だから
これが最大の理由です。Firebaseを使えば「ログインした本人だけが自分のデータを読み書きできる」という設定(セキュリティルール)を、追加コードなしで簡単に書けます。他社サービスだと、ここを繋ぐのが少し大変です。 - 日本語の情報量が圧倒的だから
歴史が長くユーザー数が多いため、エラーが出ても日本語で検索すればすぐに答えが見つかります。Clerkなどはまだ英語情報が中心です。 - 無料で使える範囲が広いから
個人開発レベルであれば、実質無制限に近い感覚で無料で使い倒せます。
4. 【準備】Firebase側での設定手順
では、実装に入りましょう。まずはFirebaseの管理画面(コンソール)にログインして利用できる状態に設定します。
※前回の記事でプロジェクト作成までは完了している前提です。
Step 1: Authenticationを有効にする
- Firebaseコンソールの左メニューから「Authentication」をクリック。
- 「始める」ボタンをクリック。
Step 2: ログイン方法を選ぶ(今回はGoogle認証)
今回は最も簡単でユーザー体験が良い「Googleログイン」を設定します。
- 「ログインプロバイダ」のタブで「Google」を選択。
- 右上のスイッチを「有効」にする。
- プロジェクトのサポートメール(自分のGmail)を選択し、「保存」をクリック。
これで裏側の準備は完了です!
5. 【実装】Next.jsでログインボタンを作る
ここからはVS Codeでの作業です。
「メモアプリ」の入り口として、ログインボタンを設置してみましょう。
① 必要なツールを入れる
ターミナルで以下のコマンドを実行し、Firebaseを扱えるようにします。
npm install firebase
①-2. 【重要】「鍵」を環境変数ファイルにセットする
Firebaseを動かすための「APIキー」を、プロジェクトに登録します。
直接コードに書くと危険なので、「.env.local」という専用のファイルを使います。
手順:
- VS Codeのプロジェクトの一番上の階層(package.jsonがある場所)に、
.env.localという名前でファイルを新規作成します。 - 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」を使って、ログインした人だけが読み書きできるメモ機能を実装します。