👏

NextAuth v5 (Beta版) のざっくりとした使い方とVercelにデプロイするときに躓きまくったので注意点をまとめてみた

2024/09/06に公開

はじめに

こんにちは!
私は今年の四月からプログラミングを初めてNext.jsの虜になっている大学一年生です。

今回は初学者の私がNextAuth v5を使ったプロジェクトをVercelにデプロイするのに一時間強かかってしまったので、失敗と注意点を共有しようと思います。
v5はBeta版ということもあり、情報源も多くはないので参考になれば幸いです。

NextAuth v5の簡単なセットアップ手順

NextAuth v5の実装がしてあるテンプレート
https://github.com/skmtrd/Next-AppRouter-template

NextAuth v5の公式ドキュメント

開発環境:
Next.js (AppRouter)
RouteHandler
PostgreSQL(Supabase), Prisma

この記事の本題ではないのでパッケージのインストールなど細かいところは省いています。

デプロイで詰まっている方は次の目次まで飛ばしてください!

1. NextAuth v5のインストール

npm i next-auth@beta

@betaとしないとv5がインストールできないので気をつけて下さい!

2. 各種ファイルの作成

プロジェクトのルート直下に作成します

auth.ts
import { prisma } from '@/lib/prisma';
import { PrismaAdapter } from '@auth/prisma-adapter';
import NextAuth from 'next-auth';
import Google from 'next-auth/providers/google';

export const { handlers, signIn, signOut, auth } = NextAuth({
  //任意のadapterを設定
  adapter: PrismaAdapter(prisma),
  //任意のプロバイダーを設定
  providers: [Google],
 secret: process.env.AUTH_SECRET,
});

各種ORMに応じたAdapterを設定するだけでDBとのやり取りをすべてやってくれます!
ここで初学者は感動...
各種ORMの設定は↓から
Adapterに関するドキュメント

./app/auth/[...nextauth]/route.ts
import { handlers } from '@/auth';
export const { GET, POST } = handlers;
middleware.ts
export { auth as middleware } from './auth';

フロントの記述をしていきます。

/components/SignIn.tsx
import { signIn } from '@/auth';

const SignIn = () => {
  return (
    <form
      className='rounded-xl p-3 ring-1 ring-slate-400'
      action={async () => {
        'use server';
        //任意のプロバイダー
        await signIn('google');
      }}
    >
      <button type='submit'>Signin with Google</button>
    </form>
  );
};

export default SignIn;
/components/SignOut.tsx
import { signOut } from '../../auth';

const SignOut = () => {
  return (
    <form
      className='grid place-items-center rounded-xl p-3 ring-1 ring-slate-400'
      action={async () => {
        'use server';
        await signOut();
      }}
    >
      <button type='submit'>SignOut</button>
    </form>
  );
};

export default SignOut;

あとはこの二つを使って簡単なページを作成します。
今回はログインをしたらセッションが表示されるようなページです。

./app/page.tsx
import SignIn from '@/components/SignIn';
import SignOut from '@/components/SignOut';
import Image from 'next/image';
import { auth } from '@/auth';

const Home = async () => {
  const session = await auth();

  return (
    <div className='flex h-screen w-full flex-col items-center justify-center gap-y-10'>
      <div className='flex'>
        {!session?.user?.image ? (
          <SignIn />
        ) : (
          <div className='flex gap-4'>
            <SignOut />
            <Image
              src={session.user.image}
              style={{ borderRadius: '50%', objectFit: 'cover' }}
              alt='image of user'
              width={60}
              height={20}
            ></Image>
          </div>
        )}
      </div>
      <div className='w-10/12 rounded-xl bg-slate-200'>
        <div className='rounded-t-xl bg-slate-400 p-3'>current session</div>
        <pre className='break-words p-3'>{JSON.stringify(session, null, 2)}</pre>
      </div>
    </div>
  );
};
export default Home;

auth関数でセッションの情報をすべて持ってきてくれます(優秀)

const session = await auth()

3.環境変数の設定

今回設定する環境変数は、

.env.local
//ひとそれぞれ!
DATABASE_URL=******************************************************

//NextAuthに必要
AUTH_GOOGLE_ID=*************************************
AUTH_GOOGLE_SECRET=***************
AUTH_SECRET=********************************************

AUTH_[任意のプロバイダー]_IDAUTH_[任意のプロバイダー]_SECRETの取得はドキュメントにしてください。

AUTH_SECRETはターミナルでこのコマンドを打ち込んで出力されたものをぶちこんで下さい。

openssl rand -base64 32

AUTH_SECRETはいろんなところで"NEXTAUTH-SECRET"と記述されているのを見かけますがデプロイの際は前者の書き方が正しいと思われます(少なくともv5では)

Vercelデプロイの躓きポイント

ここから本題です!

躓きポイント1

サインインボタン押したらこれ


プロバイダーにもよりますが認証するリダイレクトURLを入れる必要がありますね。
Googleならこんなような入力欄

ここでミスって欲しくないのは

  • Vercelのメインのドメインを入れることです。
    くれぐれもデプロイごとに発行されるドメインを入力しないようにしてください!
  • ちゃんと[domain]/api/auth/callback/googleの形式にすること

    ↑一番上!!

躓きポイント2

ログインでアカウント選択したらSeverError

ここは大トラップです!
いけた!と思ったら謎エラー。
まず確認して欲しいのはauth.tsです。

auth.ts
export const { handlers, signIn, signOut, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [Google],
  //⇩ここ!!!!!!!!!!!
  secret: process.env.AUTH_SECRET,
});

このシークレットの記述、公式ドキュメント通りにやるとすっ飛ばしてしますので迷宮入りします!
絶対に記述して押してください!

これでも治らない場合は環境変数が正しく入力できているか確認してださい!
何気にやりがちなミスです。私はシークレットに見事に empty の五文字が入っていて大横転しました。

躓きポイント3

完成!!!だけど認証の処理が遅い...

忘れがちなリージョンの設定です!
VercelでTokyoにしら再デプロイを忘れずに。

最後に

みなさんの悩みが解決できていたら嬉しいです!
そしてNextAuth v5はとても使いやすく優秀なので是非使ってみてください!

初Zennで拙い記事になってしまいましたが最後までお読みいただきありがとうございました!

X(Twitter)やってます。エンジニアの方との交流を増やしたので是非フォローを...(小声)
https://x.com/rd_1223

Discussion