在Next.js Edge Runtime的Auth.js中间件中使用Redis遇'dns'模块错误
在Next.js + Auth.js v5中使用Redis存储会话的解决方案(适配Edge Runtime)
问题概述
我在Next.js 14应用中使用Auth.js v5作为认证库,通过Unstorage的Redis适配器存储会话数据。内存存储可正常运行但不适用于生产环境,切换到Redis后启动应用报错:Cannot read properties of undefined (reading 'charCodeAt')。排查发现错误根源是ioredis依赖Node.js专属的dns等核心模块,而认证逻辑运行在Edge Runtime的middleware中,这类模块无法在Edge环境使用。
想确认:
- 是否可以在Auth.js的Next.js应用中用Redis存储会话和用户信息?
- 是否遗漏了关键配置?
版本信息
- react: 18
- next: 14.2.4
- next-auth: 5.0.0-beta.19
- unstorage: 1.10.2
- ioredis: 5.4.1
复现步骤
- 执行初始化命令:
npx create-next-app@latest cd my-app npm install next-auth@beta npx auth secret npm install unstorage @auth/unstorage-adapter ioredis
- 创建核心文件:
./auth.ts
import NextAuth from "next-auth" import { UnstorageAdapter } from "@auth/unstorage-adapter" import redisDriver from "unstorage/drivers/redis" import { createStorage } from "unstorage" const storage = createStorage({ driver: redisDriver({ host: 'localhost', tls: false as any, port: 6379 }), }); export const { handlers, auth, signIn, signOut } = NextAuth({ adapter: UnstorageAdapter(storage), providers: [], })
./middleware.ts
export { auth as middleware } from "@/auth"
./app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth" export const { GET, POST } = handlers
- 启动应用:
npx next dev
解决方案
核心问题是ioredis不兼容Edge Runtime,因为Edge环境不提供Node.js的核心模块(如dns、net)。以下两种方案可解决该问题:
方案1:改用兼容Edge的Redis驱动
替换Unstorage的Redis驱动为基于@upstash/redis的实现,它原生支持Edge Runtime:
- 安装依赖:
npm install @upstash/redis unstorage @auth/unstorage-adapter
- 修改
auth.ts配置:
import NextAuth from "next-auth" import { UnstorageAdapter } from "@auth/unstorage-adapter" import { createStorage } from "unstorage" import { upstashRedisDriver } from "unstorage/drivers/upstash-redis" import { Redis } from "@upstash/redis" // 配置Redis连接(本地或云服务均可) const redis = new Redis({ url: "你的Redis服务地址", token: "你的Redis访问令牌", // 本地Redis可省略该字段 }) const storage = createStorage({ driver: upstashRedisDriver({ redis }), }) export const { handlers, auth, signIn, signOut } = NextAuth({ adapter: UnstorageAdapter(storage), providers: [], })
方案2:分离运行环境,用JWT处理Edge会话验证
如果坚持使用ioredis,可让Auth.js适配器仅在Node.js环境运行,Edge中间件通过JWT实现无状态会话验证:
- 修改
auth.ts配置:
import NextAuth from "next-auth" import { UnstorageAdapter } from "@auth/unstorage-adapter" import redisDriver from "unstorage/drivers/redis" import { createStorage } from "unstorage" // 仅在Node.js环境初始化Redis存储 const storage = process.env.NODE_ENV !== "edge" ? createStorage({ driver: redisDriver({ host: 'localhost', port: 6379, tls: false, }), }) : undefined export const { handlers, auth, signIn, signOut } = NextAuth({ adapter: storage ? UnstorageAdapter(storage) : undefined, providers: [], session: { strategy: "jwt" }, // 启用JWT无状态会话 runtime: "nodejs", // 指定API路由使用Node.js运行时 })
- 此时middleware中的
auth函数会通过JWT验证会话,无需访问Redis,避免触发ioredis的不兼容代码。
关键注意事项
- Edge Runtime不支持Node.js核心模块,任何依赖这类模块的库都无法在该环境运行。
- Auth.js v5的
auth函数在middleware中默认使用Edge Runtime,因此适配器代码不能包含不兼容Edge的逻辑。 - Upstash Redis是为Serverless/Edge环境设计的客户端,是这类场景下Redis存储的首选方案。
内容的提问来源于stack exchange,提问作者Marcelo Barros
相关产品推荐
相关产品推荐

