在非App目录使用Clerk auth()报错,寻求解决方法
问题解决:Clerk auth()在App Router Edge Runtime中报错
你遇到的报错核心原因是Edge Runtime不支持Node.js的requestAsyncStorage,而默认的auth()调用依赖这个机制自动获取请求上下文,所以必须手动传递请求对象给auth()函数。
解决方案步骤
- 在调用
auth()时,把当前的req对象作为参数传入,这是Edge环境下Clerk获取认证信息的正确方式。 - 确认你的API文件确实放在
/app目录下的api子文件夹里(比如/app/api/notes/route.ts),确保是App Router的路由结构。
修改后的完整代码
import { db } from "@/lib/db"; import { $notes } from "@/lib/db/schema"; import { generateImage, generateImagePrompt } from "@/lib/openai"; import { auth } from "@clerk/nextjs"; import { NextResponse } from "next/server"; export const runtime = "edge"; export async function POST(req: Request) { // 关键修改:将req传入auth()以提供上下文 const { userId } = auth({ req }); if (!userId) { return new NextResponse("unauthorised", { status: 401 }); } const body = await req.json(); const { name } = body; const image_description = await generateImagePrompt(name); if (!image_description) { return new NextResponse("failed to generate image description", { status: 500, }); } const image_url = await generateImage(image_description); if (!image_url) { return new NextResponse("failed to generate image ", { status: 500, }); } const note_ids = await db .insert($notes) .values({ name, userId, imageUrl: image_url, }) .returning({ insertedId: $notes.id, }); return NextResponse.json({ note_id: note_ids[0].insertedId, }); }
补充说明
修改后,Clerk就能通过传入的req对象获取认证所需的headers等信息,解决requestAsyncStorage不可用的问题。如果你的API路由不在/app目录下才需要用getAuth(),但你这里使用的是App Router,所以仅需调整auth()的调用方式即可。
内容的提问来源于stack exchange,提问作者Herminio Henriques
相关产品推荐
相关产品推荐

