Next.jsをNextAuth.js v4からAuth.js(NextAuth.js v5)に移行する
はじめに
Auth.jsは、Next.js用に開発されていたNextAuth.jsから進化し、標準的なWeb APIをベースとした認証ライブラリです。
Next.jsなどのフレームワークでログインやセッション管理をするには定番のライブラリと言っていいでしょう。
NextAuth.js v4からNextAuth.js(Auth.js) v5に移行するにあたって、いくつか破壊的変更が入ったので設定ファイルや各種メソッドの呼び出し等を変更し、移行する必要があります。
執筆現在(2024/12/07)ではAuth.js v5はbeta版ですが、移行準備をしたり、さっさと乗り換えたいという人向けの記事です。
現在のAuth.js公式ドキュメントのアップグレードガイドを読んだだけでは分からないところも書いていきます。
前提とする環境
- Next.js v14以上
- Auth.jsがNext.js v14以上を要求するため
- NextAuth.js v4を設定した環境
手順
1. npmパッケージを最新に更新する
まず、NextAuth.js v4からAuth.js v5にアップグレードします。
※ 執筆現在は、まだbetaであることに留意してください
npm install next-auth@beta
2. 空の設定ファイルの作成
auth.ts
とauth.config.ts
ファイルを作成します。
多くの場合は、プロジェクルートの直下か、src
ディレクトリでソースを管理している場合はsrc
直下にファイルを作成することになるでしょう。
3. 設定ファイルの内容を移す
NextAuth.js v4のファイル内容をv5に移行しましょう。
ここでは実際に移行したファイルを例にします。
import { FirestoreAdapter } from "@auth/firebase-adapter";
import { cert } from "firebase-admin/app";
import { type Adapter } from "next-auth/adapters";
import GoogleProvider from "next-auth/providers/google";
import { type GoogleProfile } from "next-auth/providers/google";
import type { JWT, NextAuthOptions, Session } from "next-auth";
export const nextAuthOptions: NextAuthOptions = {
debug: process.env.NODE_ENV === "production" ? false : true,
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
authorization: {
...
},
profile(profile: GoogleProfile) {
...
},
}),
],
secret: process.env.NEXTAUTH_SECRET,
session: {
strategy: "jwt",
},
adapter: FirestoreAdapter({
...
}) as Adapter,
callbacks: {
async jwt({ token, user, account, trigger, session }) {
...
},
async session({ session, token }: { session: Session; token: JWT }) {
...
},
},
};
設定ファイルを移行して以下のようになりました。
import NextAuth from "next-auth";
import { FirestoreAdapter } from "@auth/firebase-adapter";
import { cert } from "firebase-admin/app";
import { type Adapter } from "next-auth/adapters";
import authConfig from "./auth.config";
export const { auth, handlers, signIn, signOut } = NextAuth({
session: {
strategy: "jwt",
},
adapter: FirestoreAdapter({
...
}) as Adapter,
...authConfig,
});
import type { NextAuthConfig } from "next-auth";
import { type GoogleProfile } from "next-auth/providers/google";
import Google from "next-auth/providers/google";
export default {
debug: process.env.NODE_ENV === "production" ? false : true,
providers: [
Google({
authorization: {
...
},
profile(profile: GoogleProfile) {
...
},
}),
],
secret: process.env.NEXTAUTH_SECRET,
callbacks: {
async jwt({ token, user, account, trigger, session }) {
...
},
async session({ session, token }) {
...
},
},
} satisfies NextAuthConfig;
設定ファイル移行のポイント
- 設定ファイルでエクスポートする内容が変わっています。
- import type { NextAuthOptions } from "next-auth";
+ import NextAuth from "next-auth";
- export const nextAuthOptions: NextAuthOptions = {
+ export const { auth, handlers, signIn, signOut } = NextAuth({
...
- };
+ });
- secretオプションの指定が必要なくなりました。環境変数はデフォルトで
AUTH_SECRET
を読み込むようになっています。
- secret: process.env.NEXTAUTH_SECRET,
- 各種の
providers
のimport文のパスが変わりました
- import GoogleProvider from "next-auth/providers/google";
+ import Google from "next-auth/providers/google";
- それに伴って下記のように
providers
で省略できるオプションが増えています。- 例えば
GOOGLE_CLIENT_ID
はAUTH_GOOGLE_ID
に、GOOGLE_CLIENT_SECRET
はAUTH_GOOGLE_SECRET
に名称を変更すれば自動で読み込まれます。
- 例えば
- GoogleProvider({
+ Google({
- clientId: process.env.GOOGLE_CLIENT_ID!,
- clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
authorization: {
...
},
profile(profile: GoogleProfile) {
...
},
}),
- 設定ファイルの型の書き方が変わりました
- export const nextAuthOptions: NextAuthOptions = {
+ export default {
...
- };
+ } satisfies NextAuthConfig;
-
adapter
とsession
以外はauth.config.ts
ファイルに定義を移動しています-
adapter
とsession
をauth.ts
に書かなければいけない理由は公式ドキュメントに書いてあります
-
export const { auth, handlers, signIn, signOut } = NextAuth({
session: {
strategy: "jwt",
},
adapter: FirestoreAdapter({
...
}) as Adapter,
...authConfig,
});
4. APIルートを書き換える
設定ファイルは2行で済むようになりました。
(1) NextAuth.js v4
import NextAuth from "next-auth";
import { nextAuthOptions } from "@/app/next-auth-options";
const handler = NextAuth(nextAuthOptions);
export { handler as GET, handler as POST };
(2) NextAuth.js v5
import { handlers } from "@/auth";
export const { GET, POST } = handlers;
5. 環境変数を変更する
- 殆どの環境では
NEXTAUTH_URL
やAUTH_URL
の記述は必要なくなりました- リクエストヘッダーに基づき自動で上記が設定されるようになっています
-
NEXTAUTH_SECRET
はAUTH_SECRET
になりました - 前述のように
GOOGLE_CLIENT_ID
はAUTH_GOOGLE_ID
に、GOOGLE_CLIENT_SECRET
はAUTH_GOOGLE_SECRET
に名称を変更します。- 命名ルールは下記のとおりです
AUTH_[PROVIDER]_ID=
AUTH_[PROVIDER]_SECRET=
参考: Auth.js | Environment Variables
6. middlewareを書き換える
middlewareは下記のようにラップして書くようになりました。
import authConfig from "./auth.config"
import NextAuth from "next-auth"
const { auth } = NextAuth(authConfig)
export default auth(async function middleware(req: NextRequest) {
// ミドルウェアの処理をここに書く
})
7. セッションの取得処理を書き換える
サーバーコンポーネントでのセッションの取得方法がgetServerSession()
ではなくauth()
で取得できるようになりました。
シンプルですね。
getServerSession()
を使っている箇所を片っ端からauth()
に変更しましょう。
クライアントコンポーネントでは従来通りuseSession()
を用いて取得します。
- import { authOptions } from "pages/api/auth/[...nextauth]"
- import { getServerSession } from "next-auth/next"
+ import { auth } from "@/auth"
export default async function Page() {
- const session = await getServerSession(authOptions)
+ const session = await auth()
return (<p>Welcome {session?.user.name}!</p>)
}
最後に
以上がNextAuth.js v4からNextAuth.js(Auth.js) v5に移行するにあたって自分が対応した内容になります。
動かなくなった時はAuth.js公式ドキュメントのアップグレードガイドなどの公式ドキュメントやAuth.jsのソースなどを参考にすることをお勧めします。
読んで頂き、ありがとうございました!!
Discussion