2024-07-05
【Tips - NextAuth.js】実例でわかるシリーズ
みなさんどうも、こんばんみ~。ぎょうざです。
Webアプリ上などで、ユーザー認証やログイン機能などを実装する際に便利なライブラリ「NextAuth.js」を利用する際に、ぎょうざが躓いたエラーや警告を、原因と解決策のセットで備忘録として記録しておきます。
同じ現象で、画面とにらめっこが終わらない方々の参考になれば幸いです。
検証環境
- Next.js (App Router)
- NextAuth.js v4
- ORM: Prisma
- Database: Supabase (PostgreSQL)
【目次】
<Useful> ▶ NEXTAUTH_SECRET はワンライナーで作る <Error> ▶ Error: This Action(もしくはAction signIn) with HTTP GET is not supported by NextAuth.js ▶ Google認証画面で「400: redirect_uri_mismatch」が表示される(GET /api/auth/providers 400なども) ▶ [next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR] <Warn> ▶ [next-auth][warn][NEXTAUTH_URL] 〆の一言
<Useful>
▶ NEXTAUTH_SECRET はワンライナーで作る
.env に設定する NEXTAUTH_SECRET の値は、ターミナルで以下のコマンドを実行して生成したランダム文字列を使うのが手軽で安全です。
openssl rand -base64 32
<Error>
▶ Error: This Action(もしくはAction signIn) with HTTP GET is not supported by NextAuth.js
- 現象:認証画面のURLにアクセスした際、ブラウザ上に上記エラーが表示される
- 原因:
NEXTAUTH_URLまたはNEXTAUTH_SECRETが環境設定用ファイル(例:.envまたは.env.localなど)にない - 解決策:
NEXTAUTH_URLにhttp://localhost:3000、またNEXTAUTH_SECRETに任意の値(ターミナル上でopenssl rand -base64 32による生成がオススメ)を環境設定用ファイル(例:.env)に記述する
▶ Google認証画面で「400: redirect_uri_mismatch」が表示される(GET /api/auth/providers 400なども)
- 現象:Google認証画面上で技術的なエラーという文言は表示されるが、ログインするGoogleアカウントが表示されない
- 原因:開発環境のフォルダ階層が以下のように、コールバックのフォーマットに沿っていなかった
# 誤
app
-api
-[...nextauth]
-route.ts
-auth # 正
app
-api
-auth
-[...nextauth]
-route.ts - 解決策:上記の通り
app/api/auth/[...nextauth]/route.tsの階層に配置し直す
🥴
上記で解決しない場合は、Google Cloud Consoleの「OAuth 2.0 クライアント ID」設定で、承認済みのリダイレクトURIが以下のように正しく登録されているか確認してください。末尾のパスやポート番号にズレがないか要チェックです
http:localhost:3000/api/auth/callback/google
▶ [next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR]
- 現象:コールバック時に
Invalid prisma.account.findUnique() invocationが発生し、SupabaseのDBに接続できない。 - 原因:Supabaseのデータベースパスワードに特殊文字(
@や#など)が含まれており、接続文字列(DATABASE_URL)のパースが壊れていた
Please make sure your database server is running at `~~~(各自のデータベースURIのホスト名)~~~`. {
message: '\n' +
'Invalid `prisma.account.findUnique()` invocation:\n' +
'\n' +
'\n' +
"Can't reach database server at `~~~(各自のデータベースURIのホスト名)~~~`\n" +
'\n' +
'Please make sure your database server is running at `~~~(各自のデータベースURIのホスト名)~~~`.',
stack: 'PrismaClientInitializationError: \n' +
'Invalid `prisma.account.findUnique()` invocation:\n' +
'\n' +
'\n' +
"Can't reach database server at `~~~(各自のデータベースURIのホスト名)~~~`\n" +
'\n' +
'Please make sure your database server is running at `~~~(各自のデータベースURIのホスト名)~~~`.\n' +
' at _n.handleRequestError (~~~(ソースコードがあるディレクトリ)~~~\\node_modules\\@prisma\\client\\runtime\\library.js:122:7227)\n' +
' at _n.handleAndLogRequestError (~~~(ソースコードがあるディレクトリ)~~~\\node_modules\\@prisma\\client\\runtime\\library.js:122:6235)\n' +
' at _n.request (~~~(ソースコードがあるディレクトリ)~~~\\node_modules\\@prisma\\client\\runtime\\library.js:122:5919)\n' +
' at async l (~~~(ソースコードがあるディレクトリ)~~~\\node_modules\\@prisma\\client\\runtime\\library.js:131:9116)\n' +
' at async getUserByAccount (webpack-internal:///(rsc)/./node_modules/@next-auth/prisma-adapter/dist/index.js:211:29)',
name: 'PrismaClientInitializationError'
} 参考:https://next-auth.js.org/errors#oauth_callback_handler_error
- 解決策:Stack Overflowなど読み漁った。
→最終的な解決策:Supabaseのデータベースのパスワード文字列に@ が含まれていることが原因である可能性にたどり着き、試しに記号を使わず英数字のみのパスワードにリセットした結果、Googleアカウント認証登録に成功した。開発環境ターミナル上のログでも認証情報が読み取れていることを確認できた。
POST /api/auth/signin/google 200 in 210ms
[next-auth][debug][PROFILE_DATA] {
OAuthProfile: {
iss: 'https://accounts.google.com',
azp: '~~~(各自のGoogle Cloud Console上のGoogle認証APIで発行されたID)~~~',
aud: '~~~(各自のGoogle Cloud Console上のGoogle認証APIで発行されたID)~~~',
sub: '~~~(各自の値)~~~',
email: '~~~(Google認証に使用したGoogleアカウントのメールアドレス)~~~',
email_verified: true,
at_hash: '~~~(各自の値)~~~',
name: '~~~(各自のGoogle認証に使用したGoogleアカウントのユーザー名(後述のgiven_name + family_name))~~~',
picture: '~~~(各自の値)~~~',
given_name: '~~~(各自のGoogle認証に使用したGoogleアカウントのFirst Name)~~~',
family_name: '~~~(各自のGoogle認証に使用したGoogleアカウントのLast Name)~~~',
iat: 1720334515,
exp: 1720338115
}
} ぎょうざコメント:原因にたどり着くまで1時間ほどネットを彷徨いましたわ。。。
<Warn>
▶ [next-auth][warn][NEXTAUTH_URL]
- 現象:開発ターミナル上に上記の警告表示される
- 原因:next-auth側の仕様、ローカル開発時に
NEXTAUTH_URLが明示されていないため - 解決策:環境設定用ファイル(例:.env)に
NEXTAUTH_URLにhttp://localhost:3000を設定する
〆の一言
振り返ってみると、ディレクトリ配置の1階層ミスや、URL・接続文字列の特殊文字によるエラーなど、設定周りの細かい部分で詰まるケースが大半でした。だいたいフォルダ階層の配置ミス、URL文字列タイポによるエラーが多い。。。
ここまで読んでいただき、ありがとうございました。
以上、某ぎょうざでした。