🦁
PrismaAdapterを使うとNextAuth.jsのmiddlewareが機能しなかった
これはなに
Next.jsのアプリケーションを作成時にNextAuth.jsを使い認証機能を作成しました。
その際に、ログインしているユーザーのみに見せたいページがあり、NextAuth.jsのmiddlewareを使ったのですが、上手く機能しなかったので、そのことについて書いていきます。
原因
NextAuth.jsでAdapterを使用すると、デフォルトがデータベースセッションになってしまうから。
例
NextAuth.jsのPrismaAdapterを使いGoogleアカウントでログインできる機能を作成しました。
src/pages/api/auth/[...nextauth.ts]
import NextAuth from 'next-auth'
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import Google from 'next-auth/providers/google'
import prisma from "../../../../lib/prisma"
export default NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
})
],
secret: process.env.SECRET,
})
NextAuth.jsのmiddlewareを使うと、以下のように記載するだけでログインしているユーザーだけ/me
ページが見れるようになるはずです。
src/middleware.ts
export { default } from "next-auth/middleware"
export const config = {
matcher: [
"/me"
],
}
しかし、NextAuth.jsのmiddlewareではJWTを使い認証をしています。そのためPrismaAdapterを使用するとデフォルトがデータベースセッションになってしまうため、middlewareが機能せず一生SignInページにリダイレクトされます。
解決策
明示的にJWTを指定します。
src/pages/api/auth/[...nextauth.ts]
import NextAuth from 'next-auth'
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import Google from 'next-auth/providers/google'
import prisma from "../../../../lib/prisma"
export default NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
})
],
session: {
strategy: "jwt",
},
secret: process.env.SECRET,
})
NextAuth.jsのmiddlewareの注意書きにも以下のように書かれています。
Only supports the "jwt" session strategy. We need to wait until databases at the Edge become mature enough to ensure a fast experience. (If you know of an Edge-compatible database, we would like if you proposed a new Adapter)
参考
Discussion