Kento
Next.jsのmiddlewareでPrismaを読み込み、Edge Runtimeエラーが発生した原因と対処
2026年08月15日
見出しはありません
要約を生成中...
Next.jsのmiddlewareでPrisma読み込んだら、The edge runtime does not support Node.js 'crypto' module.とエラーに遭遇したので、メモとして記録に残しています。
前提
背景
原因
解決方法
用語集
おわり
使用技術は以下のとおり。
Next.js(App Router)
Prisma(ORM)
Auth.js(認証)
PostgreSql(DB)
ログイン認証の実装において、Next.jsのmiddlewareを使って、アクセス制御の実装をしてました。 Next.jsのmiddlewareは、従来のNode.Jsランタイムではなく、現在はEdgeランタイムで実行され、ユーザーに近い距離でリクエスト処理ができるサポートをしてくれています。 今回の実装では、middlewareにAuth.js認証設定を記述してあるauth.tsを読み込んでいた。
以下公式にも記述されています。
auth.tsでは、Prisma Adapterやbcryptなど、Node.jsの機能に依存するライブラリを使用していた。
そのauth.tsをEdge Runtimeで動くMiddlewareから読み込んだため、次のエラーが発生した。The edge runtime does not support Node.js 'crypto' module.とエラーとなった。
Edgeランタイムを実行するためにmiddlewareに、Prisma Adapterやbcryptを読み込ませないように分割しました。
このファイル自体が自動的に、Edgeランタイムを実行するのではなく、 middlewareから読み込まれた場合に、Edgeランタイム上で使用されるようにしています。
// auth.config.ts
import type { NextAuthConfig } from "next-auth";
const authConfig = {
providers: [],
} satisfies NextAuthConfig;
export default authConfig;
auth.config.tsでは、auth.tsでNode.jsランタイムで動く用とmiddleware.tsでEdgeランタイムで動く用で共通して使えるようにするってことです。
┌→ middleware.ts
auth.config.ts ───┤ Edge Runtime
│
└→ auth.ts
Node.js Runtime
以下は、ログイン機能の認証ロジック設定。
// auth.ts
import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { PrismaAdapter } from "@auth/prisma-adapter";
import bcrypt from "bcrypt";
import authConfig from "./auth.config";
import { prisma } from "@/lib/prisma";
import { signInSchema } from "@/features/auth/schemas/signInSchema";
import { getUserByEmail } from "@/features/auth/repositories/user";
// ログイン機能の検証ロジックの設定
// 認証プロバイダーとして、Credentialsを使用。
/*
Credentialsは、ユーザー名とパスワードを使用して認証するためのプロバイダー。
Credentialsを使用すると、ユーザー名と話スワードを使用して認証するためのカスタム認証ロジックを実装することができる。
authorizeメソッドは、認証に成功した場合はユーザーを返し、失敗の場合はnullを返す。
成功した場合のユーザー情報は、セッションとして保存される。
*/
// authorizeは、認証に本当に成功したのかを判断する。
/*
・受け取った認証情報を検証する。
・メールアドレス・ユーザーを検索する。
・入力されたパスワードとハッシュを照合する。
・成功ならユーザーに返す。
・失敗ならnullを返す。
*/
export const {
handlers: { GET, POST },
auth,
signIn,
signOut,
} = NextAuth({
...authConfig,
adapter: PrismaAdapter(prisma),
session: {
strategy: "jwt",
},
providers: [
// TODO: Google認証を追加する
Credentials({
async authorize(credentials) {
const validatedFields =
signInSchema.safeParse(credentials);
if (!validatedFields.success) {
return null;
}
const { email, password } = validatedFields.data;
const user = await getUserByEmail(email);
if (!user || !user.password_hash) {
return null;
}
const passwordsMatch = await bcrypt.compare(
password,
user.password_hash
);
return passwordsMatch ? user : null;
},
}),
],
});
```
NextAuth({
...authConfig,
adapter: PrismaAdapter(prisma),
session: {
strategy: "jwt",
},
providers: [
// TODO: Google認証を追加する
Credentials({
async authorize(credentials) {
// DB検索とパスワード照合
},
}),
],
});auth.tsには、Node.jsの必要な機能をかく。
ここでは、以下の処理を書いています。
DBの操作(ユーザー検索)
パスワードのハッシュ化済みのパスワードの照合
Prisma Adapterの使用
Credentials認証(GoogleやGitHubなどの外部サービスを使わず、独自のID(メールアドレス等)とパスワードでログインを行う従来型の認証方式)
JWTセッションの生成に必要な認証処理
Node.js Runtime
DB操作やパスワード照合など、実際のログイン認証を行う
Edge Runtime
リクエストを受け取り、ページへのアクセス可否を素早く判断する
クライアントとサーバーの中間のリクエスト処理をする仕組み。
ユーザーの近い距離で、JavaScriptコードを実行する軽量なサーバーレス実行環境。
軽いけど、Node.jsモジュールの機能が一部制限されています。(fs(ファイルシステム), http, crypto(暗号処理))
レンダリングやAPI, ミドルウェアなどを実行するための、Node.jsベースの実行環境。
Node.jsのAPIやファイルシステム、npmが使えるようになる。
データベースを接続するためのアダプター、認証ライブラリ(Auth.js)用のアダプターです。
役割としては、Prismaを介してデータベースを操作や検索を行えるようにする。
Prismaで書いたコードを、DBが理解できるように翻訳をしてくれます。
Node.jsのモジュール機能の中の一つで、ランダムな値の生成・パスワードのハッシュ化などで役立ちます。
今回のエラーで、Next.jsのmiddlewareでは、edge runtimeがサポートされていることが理解きました。
また、Node.js RuntimeとEdge Runtimeのそれぞれの役割を理解することで、色々と便利に使えることができたので、勉強になりました。
要約
コメント
まだコメントはありません。