Next.js Edge Runtime不支持Node.js crypto模块错误求助
Next.js Middleware报错:The edge runtime does not support Node.js 'crypto' module
问题原因
- Next.js 中间件默认运行在Edge Runtime环境,这个环境不支持Node.js核心模块(比如
crypto),而你使用的jsonwebtoken库依赖Node.js的crypto模块,直接调用就会触发报错。 - 另外你在中间件里直接连接MongoDB,Edge Runtime对MongoDB原生客户端的支持也很差,因为它依赖Node.js专属的网络API。
解决办法
1. 替换JWT库为Edge兼容版本
用纯JS实现、不依赖Node.js核心模块的jose库替代jsonwebtoken,它完全适配Edge Runtime。
2. 移除中间件中的MongoDB操作
中间件只做JWT合法性校验(确保token未过期、签名正确),用户是否存在的校验逻辑移到API路由中——API路由默认使用Node.js Runtime,可以正常使用MongoDB客户端和jsonwebtoken。
修改后的代码示例
调整后的middleware.ts
import { NextResponse, NextRequest } from "next/server"; import { jwtVerify } from "jose"; interface RequestWithUserId extends NextRequest { userId: string; } export async function middleware(req: RequestWithUserId) { try { const token = req.cookies.get("jwt")?.value; if (!token) { return NextResponse.redirect(new URL("/login", req.url)); } // 用jose验证JWT,无需依赖crypto模块 const secret = new TextEncoder().encode(process.env.SECRET_KEY); const { payload } = await jwtVerify(token, secret); const userId = payload._id as string; if (!userId) { return NextResponse.redirect(new URL("/login", req.url)); } req.userId = userId; return NextResponse.next(); } catch (err) { console.log("middleware error", err); return NextResponse.redirect(new URL("/login", req.url)); } } export const config = { matcher: "/api/addToCart", };
把用户存在校验移到API路由(/api/addToCart/route.ts)
import { NextRequest, NextResponse } from "next/server"; import jwt from "jsonwebtoken"; import clientPromise from "../../database/db"; export async function POST(req: NextRequest) { try { const token = req.cookies.get("jwt")?.value; if (!token) { return NextResponse.json({ error: "未授权" }, { status: 401 }); } const decodedToken: any = jwt.verify(token, process.env.SECRET_KEY); const userId = decodedToken._id; const mongoClient = await clientPromise; const checkUserExists = await mongoClient.db().collection("user").findOne({ _id: userId }); if (!checkUserExists) { return NextResponse.json({ error: "用户不存在" }, { status: 401 }); } // 这里写添加购物车的业务逻辑 return NextResponse.json({ success: true }); } catch (err) { return NextResponse.json({ error: "授权失败" }, { status: 401 }); } }
额外说明
如果一定要在中间件里做用户存在校验,不要用MongoDB原生客户端,改用MongoDB提供的Data API(HTTP接口形式),它可以在Edge环境中正常调用。
内容的提问来源于stack exchange,提问作者Aayush singh
相关产品推荐
相关产品推荐

