3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初心者必見】Next.js認証システムで初心者がハマる4つのエラーと解決法

Last updated at Posted at 2025-08-19

「ユーザー登録機能を実装したはずなのに、なぜかエラーが...」

認証機能のテストで test+admin@gmail.comuser+dev@example.com のようなGmail+エイリアス(+記号付きメール)を使ったことはありませんか?この便利な機能は、1つのメールアドレスで複数のテストユーザーを作れる開発者の強い味方ですが、実は多くの認証システムで弾かれてしまいます。

Next.js認証システムでよく遭遇する4つのエラーと解決法を、実際のログと解決過程で解説。Gmail+エイリアス対応から開発環境設定まで、再発防止の方法も紹介します。

解決できるエラー: Gmail+エイリアス対応、JWT二重検証、bcryptパスワード比較、Edge Runtime制約


🚨 エラー1: Gmail+エイリアス対応のメールバリデーションエラー

症状: user+alias@gmail.comValidation error: Invalid email format

🔍 原因: /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/\w+ 記号を含まない

💡 正規表現とは?
文字のパターンを決めるルールです。「メールアドレスはこんな形でないとダメ」という条件を文字で表現したもの。\w は「文字・数字・アンダーバー」のみ許可するため、+ 記号が弾かれてしまいます。

✅ 解決策:

match: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/

💡 RFCとは?
RFC(Request for Comments)は、インターネットの公式ルールブック。メールアドレスの正しい形を決めた国際基準で、この基準に従うと世界中で通用するメールアドレス判定ができます。

🛡️ 予防策: RFC準拠のバリデーション、Gmail+エイリアステスト必須


🚨 エラー2: JWT二重検証による「無効な認証トークン」エラー

症状: メール認証リンククリック後、必ず /auth/verify-error にリダイレクト

💡 JWTとは?
JWT(JSON Web Token)は、デジタルの身分証明書のようなもの。コンサートの入場券に偽造防止の印鑑が押してあるのと同じで、この印鑑(署名)を確認するだけで本物だとわかります。そのため、わざわざ券売所に電話して確認する必要がありません。

🔍 原因: jwt.verify() 後にDB照合も実行する二重検証が失敗原因

// 問題:JWTは自己完結型なのにDB照合も実行
jwt.verify(token, process.env.JWT_SECRET!);
if (user.emailVerificationToken !== token) { // ←これが不要

✅ 解決策:

try {
  jwt.verify(token, process.env.JWT_SECRET!);
  // JWTが検証済みなので、DB照合不要
  user.emailVerified = true;
  await user.save();
} catch (error) {
  return NextResponse.redirect(new URL('/auth/verify-error', req.url));
}

🛡️ 予防策: JWTの自己完結性理解、「シンプル=安全」原則


🚨 エラー3: bcryptパスワード比較の謎の失敗

症状: 正しいパスワードでも bcrypt.compare result: false

💡 bcryptとは?
bcryptは、パスワードを暗号に変える一方通行のシステムです。例えば「abc123」を「$2b$12$xyz...」という暗号に変換し、元のパスワードは取り出せません。ログイン時は、入力されたパスワードを同じ方法で暗号化して結果を比較します。設定が違うと同じパスワードでも異なる暗号になってしまいます。

🔍 原因: 登録時とログイン時のハッシュ化処理に不一致

✅ 解決策:

// 正しいハッシュを再生成してDB更新
const newHash = await bcrypt.hash('testpass123', 12);
await User.findByIdAndUpdate(userId, { password: newHash });

🛡️ 予防策: saltラウンド数統一(12推奨)、処理の一貫性確保


🚨 エラー4: Edge Runtime暗号化モジュールエラー

症状: The edge runtime does not support Node.js 'crypto' module

💡 Edge Runtimeとは?
Edge Runtimeは、軽量で高速な実行環境です。通常のNode.js環境と比べて、必要最小限の機能のみを搭載することで、世界中のどこにでも素早く配置でき、ユーザーに近い場所で超高速に動作します。ただし、一部の重い機能(cryptoモジュールなど)は利用できません。

🔍 原因: NextAuth + middleware.ts で Edge Runtime制約に抵触

✅ 解決策:

// JWTセッション戦略に変更
export default {
  session: { strategy: "jwt" },
  // adapter: MongoDBAdapter(clientPromise), // 削除
}

🛡️ 予防策: Edge Runtime制約事前調査、JWTセッション優先採用


認証システム設計の鉄則

  1. シンプル性の原則 - 複雑な認証フローほどバグの温床。不要な検証処理は削除
  2. 一貫性の確保 - ハッシュ化、環境変数、エラーハンドリングで統一ルール適用
  3. 環境制約の理解 - Edge Runtime、NextAuth、MongoDBの制約を事前把握
  4. 段階的なデバッグ - 複数エラー時は一つずつ解決、根本原因を特定

実践チェックリスト + 開発環境活用法

即使える認証実装チェックリスト

  • メールバリデーションがGmail+エイリアス対応済み
  • JWT検証とDB照合の重複がない
  • bcryptのsaltラウンド数が統一されている
  • Edge Runtime制約に配慮した設計になっている
  • 環境変数(JWT_SECRET、SMTP設定)が正しく設定されている

開発環境で認証エラーを未然に防ぐ設定

これらのエラーを二度と起こさないために、Claude CodeやCursorに以下のプロンプトを設定しておくことを強くおすすめします:

CLAUDE.mdやCursorのrulesに追加

# 認証システム実装チェック

## JWT実装時の必須確認
- JWT検証とDB照合の二重チェックを避ける
- JWT_SECRET環境変数の設定確認  
- トークン有効期限の適切な設定

## メール認証実装時の必須確認
- RFC準拠の正規表現使用(Gmail+エイリアス対応)
- SMTP設定の環境変数確認
- 絶対URL生成の一元化

## パスワード処理の必須確認
- bcryptハッシュ化の一貫性
- 登録時とログイン時の処理統一
- saltラウンド数の適切設定(12推奨)

## Edge Runtime制約確認
- crypto モジュール使用箇所のチェック
- middleware.tsでのNextAuth利用回避
- JWTセッション戦略への移行検討

自動化のメリット

認証機能実装時に自動的にチェックポイントが提示され、同じエラーの再発を防げます。開発時間の短縮と品質向上を同時に実現できる、初心者には特におすすめの方法です。


まとめ

Next.js認証システムの4つのエラーと解決法を紹介しました:

  1. RFC準拠のバリデーション - メール形式問題を回避
  2. JWTの特性理解 - 二重検証の罠を避ける
  3. 一貫したハッシュ化処理 - パスワード比較エラーを防ぐ
  4. Edge Runtime制約の把握 - 適切な技術選択

開発環境のプロンプト設定で、エラー再発防止と学習効果を向上させましょう。今回の解決法とチェックリストで、堅牢な認証システムを構築してください。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?