UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Next.js】Firebase Authentication で JWTを検証する

以前、Firebase AuthenticationでGoogle認証を行う方法を調べた

uga-box.hatenablog.com

今度は認証情報(JWT)を使って更新機能をつくりたい

このときAuthorization ヘッダ付与したJWTの検証をFirebase Authentication Adminで検証する必要がある

その方法を調べる

これも公式サンプルがある
github.com

手順

firebase-adminのインストール

$ npm i firebase-admin

firebaseAdmin.jsonをどこにおくかまだ悩ましいが、とりあえず/configにおきserver/firebase.jsで初期化する

import * as admin from "firebase-admin";
import firebaseAdminConfig from "../config/firebaseAdmin.json";

export function getAdmin(): admin.app.App {
  if (admin.apps.length > 0) {
    return admin.apps[0] as admin.app.App;
  } else {
    const app = admin.initializeApp({
      credential: admin.credential.cert(firebaseAdminConfig as any),
      databaseURL: process.env.FIREBASE_DATABASE_URL,
    });
    return app;
  }
}

/pages/index.jsでcurrentUserからtokenを取得する

  const updateUser = async () => {
    if (currentUser) {
      const token = await currentUser.getIdToken(true);
      const body = { id: 1 };
      const options = {
        method: "POST",
        body: JSON.stringify(body),
        headers: {
          "Content-Type": "application/json",
          Authorization: token || "",
        },
      };
      try {
        const res = await fetch(`/api/user`, options);
        const repos = await res.json();
        console.log(repos);
      } catch (err) {
        console.log(err);
      }
    }
  };

next-connectを使ってmiddlewareを用意して、そこでJWTの検証をするようにする

/middleware/auth.js

import nextConnect from "next-connect";

async function verifyIdToken(idToken: string) {
  const admin = getAdmin();
  return await admin.auth().verifyIdToken(idToken);
}

export default nextConnect ()
  .use(async (req, res, next) => {
  const idToken = req.headers["authorization"] as string;
  if (idToken != null) {
    try {
      req.body.idToken = await verifyIdToken(idToken);
      return next();
    } catch (error) {
      return res.status(401).send("You are unauthorised");
    }
  }
  next();
});

最後に/pages/api/usders.jsでauthミドルウェアを使うようにして完了

import auth from "../../middleware/auth";

const handler = nextConnect();
handler
  .use(auth)
  .post((req, res) => {
    console.log(req.body.idToken.uid);
  })

参考

https://mizchi.dev/202007271454-next-arch