API認証

1import { getIdToken, signInAnonymously, signOut } from 'firebase/auth';
2import React from 'react';
3import { useAuth } from '../context/auth';
4import { auth } from '../firebase/client';
5
6const ApiAuthGuard = () => {
7  const { firebaseUser } = useAuth();
8  const validateAPIAuth = async () => {
9    const token = auth?.currentUser
10      ? await getIdToken(auth.currentUser, true)
11      : '';
12
13    fetch('/api/auth-valid', {
14      method: 'POST',
15      headers: {
16        Authorization: 'Bearer ' + token,
17      },
18    })
19      .then(async (response) => {
20        if (!response.ok) {
21          const message = await response.text();
22          throw new Error(message);
23        }
24        return response.text();
25      })
26      .then((message: string) => {
27        alert(message);
28      })
29      .catch((error) => {
30        alert(error.message);
31      });
32  };
33
34  const login = () => {
35    signInAnonymously(auth);
36  };
37
38  const logout = () => {
39    signOut(auth);
40  };
41
42  return (
43    <div>
44      <button className="px-3 py-2 rounded border" onClick={validateAPIAuth}>
45        APIにアクセス
46      </button>
47
48      <p className="mt-4">
49        {firebaseUser ? (
50          <p>
51            ログインしています{' '}
52            <button className="text-pink-600" onClick={logout}>
53              ログアウト
54            </button>
55          </p>
56        ) : (
57          <p>
58            <button className="text-pink-600" onClick={login}>
59              ログイン
60            </button>
61            してください
62          </p>
63        )}
64      </p>
65    </div>
66  );
67};
68
69export default ApiAuthGuard;

解説

作成した Next.js の API には誰でもアクセスできます。APIの中でログイン中のユーザーデータを編集するなど秘匿性の高い処理を行っている場合、APIの実行はログイン中のユーザーにのみ許可しましょう。要するにAPI実行時に「本当にFirebaseでログインしているユーザーか?」を判断し、問題ない場合に限りAPIを実行するようにします。

実装は以下のフローで行います。

  1. ログインユーザーのIDトークンを生成する
  2. APIからアクセスする際にIDトークンをAPIに渡す
  3. API側でIDトークンの正当性を検証する

使用ライブラリ

なし

参考サイト