Open6

NextAuth v5とFirebase Authenticationで、Next.jsのバックエンドをBFFとして利用して既存APIサーバーと連携する

blackawablackawa

fetchに使う:

import { auth } from '@/app/api/auth/[...nextauth]/route'

const res = await fetch('http://localhost:8000/customers', { method: 'GET', headers: { Authorization: `Bearer ${(await auth())?.user?.token}` } })
blackawablackawa

サーバーセッションにfirebaseのアクセストークンを突っ込みたい。firebaseが払い出すアクセストークンは30分ごとに有効期限が切れてしまう & サーバーサイドで外部APIを叩きたい、という2つのモチベーションを満たすため。

getIdToken()はさすがにサーバーサイドでは動かないだろう...。ローカルストレージ使ってるし。

じゃあonIdTokenChangedコールバックを利用して更新するか。

useEffectに何も依存配列を入れないと、初回のsessionがundefinedな状態でuseEffectが走る。
一方でsession.statusなどを依存配列に入れると、useEffectが無限に走ってしまう。

かつ、どちらにせよsessioinのデータ更新は行われていないようだ。

useEffect(() => auth.onIdTokenChanged(async (user) => {
        const idToken = await user?.getIdToken()
        if (idToken && session.data?.user?.token !== idToken) {
            console.log('onIdTokenChanged: updating session id token!') // 無限にログが出る
            await session.update({ ...session.data, user: { ...session.data?.user, token: idToken } })
            console.log('updated:', session.data)
        }
    }), [session.status])

sessioinの振る舞いについてもう少し学ぼう。

sessionの型情報によると、userというプロパティを持っているらしいが、useSessionの結果取得できる値には data、statusというプロパティが生えている。

クライアントサイドでのセッション取得の項目を調べると SessionProvideruseSession で実現できる。ただしこの例は、Page Routerを使ったものだ。App Router & NextAuth v5だとどうなるかな...。

blackawablackawa

App Router と Next Auth v5でセッション更新する記事があった。
これはfirebase authとは関係ないけど、クライアントサイドで更新したセッションをサーバーサイドで更新する流れがよく分かった。

useSession() で取得した update 関数を利用すると、 POST /api/auth/session を叩くことになる。単にクライアントサイドで更新をかけるだけでなく、サーバーサイドでも更新処理を書く必要があるっぽい。

blackawablackawa

useActionStateも使いたいが、react canaryを利用する必要があるらしく、今は置く...。