🎡

create-t3-app を使って NextAuth.js v5 (beta) に 入門した

2024/05/06に公開

TL;DR

下記のコミットでやってみました。
詳しい人なら、どう変わったのかこれだけで分かってくれると思う。

https://github.com/TakashiAihara/t3light-mysql-drizzle-nextauth/commit/c71e0acfe92cdb0355ef29327516103e0c2e94ea

下記にすべてが詰まってる。

https://authjs.dev/getting-started/migrating-to-v5

前述の PR は無関係な差分も含まれているので細かく見ていく。

環境

-    "@auth/drizzle-adapter": "^0.7.0",
+    "@auth/drizzle-adapter": "^1.0.1",
-    "next-auth": "^4.24.7",
+    "next-auth": "5.0.0-beta.17",

大きな差分

大まかに変わったところ 3つ。

  • authOptions という受け渡し方が不要になった。
  • 多くのメソッドが auth() メソッドに集約された。
  • auth.ts の推奨配置場所が変わった(project root に 置くことを推奨)

変わったところ

.env ( 環境変数 )

必須の環境変数は、AUTH_SECRET のみになった。

The AUTH_SECRET environment variable is the only variable that is really necessary. You do not need to additionally pass this value into your config as the secret configuration option if you’ve set the environment variable.

NEXTAUTH_URL は 必須ではなくなった。クライアントのリクエストヘッダーから自動推測する。

The NEXTAUTH_URL/AUTH_URL is not strictly necessary anymore in most environments. We will auto-detect the host based on the request headers.

NEXT という prefix ではなくなった。

All environment variables should be prefixed with AUTH_, NEXTAUTH_ is no longer in use.

-NEXTAUTH_URL=http://localhost:3000
-NEXTAUTH_SECRET=
+AUTH_SECRET=

src/auth.ts

NextAuth の Core になる設定ファイル。
server 寄りだったが、純粋に中間に位置してきた印象。

handlers, auth などを取り出し、ここから各関数やコンポーネントに渡すようになる。

One of our goals was to avoid exporting your configuration from one file and passing it around as authOptions throughout your application. To achieve this, we settled on moving the configuration file to the root of the repository and having it export the necessary functions you can use everywhere else. (auth, signIn, signOut, handlers etc.).

それ以外の構成などはほぼ同じ。
accounts など Schema を渡す必要があったので、下記では渡しています。

export const { handlers, signIn, signOut, auth, unstable_update } = NextAuth({
  adapter: DrizzleAdapter(db, {
    accountsTable: accounts,
    usersTable: users,
    sessionsTable: sessions,
    verificationTokensTable: verificationTokens
  }),
  providers: [
    DiscordProvider({
      clientId: DISCORD_CLIENT_ID,
      clientSecret: DISCORD_CLIENT_SECRET,
    }),
  ],
...

src/app/api/auth/[...nextauth]/route.ts

authOptions を明示的に取り出して渡してあげる必要があったものの、それも必要なくなった。
2 行で終わる。

あと、いい感じに型も通っているみたい。

-import NextAuth from "next-auth";
-
-import { authOptions } from "~/server/auth";
-
-// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
-const handler = NextAuth(authOptions);
-export { handler as GET, handler as POST };
+import { handlers } from "~/auth"
+export const { GET, POST } = handlers;

src/app/page.tsx

auth() に集約されたことによって、getServer** の取り出しが不要になった。

+import { auth } from "~/auth";
-import { getServerAuthSession } from "~/server/auth";

-  const session = await getServerAuthSession();
+  const session = await auth();

src/server/api/trpc.ts

上記 page.tsx と同じく。

+import { auth } from "~/auth";
-import { getServerAuthSession } from "~/server/auth";

-  const session = await getServerAuthSession();
+  const session = await auth();

まとめ

記述量がさらに減ってうれしいですね。
ただ、auth() の責務がかなりでかく、引数の数だけで全く違った動きをする感じになりそうなので、複雑な動きを構築していく場合は要注意かも。
それを差し引いても、メリットが多そうなので早く Beta から抜けてくれ!

補足

この PR ですが、

  1. DISCORD の SECRET 等を取得する
  2. .env 作る
  3. docker compose up -d
  4. pnpm i
  5. pnpm db:push
  6. pnpm dev

で実際に動くはず。( Template 用なので README などをきれいにする想定無し)

コンテンツは create-t3-app のままなので目新しいことはないです。

Discussion