【发布时间】:2022-06-13 14:03:36
【问题描述】:
我正在使用 NextJS 创建一个网站,并使用 NextAuth 进行身份验证。该数据库在 MongoDB Atlas 中处于免费层。
我有两个版本的数据库连接代码。一个是这样的:
/**
* MongoDB Connection
*
* */
import mongoose from 'mongoose'
const MONGODB_URI = process.env.MONGODB_URL
if (! process.env.MONGODB_URL) {
throw new Error(
'Please define the MONGODB_URI environment variable inside .env.local'
)
}
/**
* Global is used here to maintain a cached connection across hot reloads
* in development. This prevents connections growing exponentially
* during API Route usage.
*/
let cached = global.mongoose
if (!cached) {
cached = global.mongoose = { conn: null, promise: null }
}
async function dbConnect() {
if (cached.conn) {
return cached.conn
}
if (!cached.promise) {
const opts = {
useNewUrlParser: true,
useUnifiedTopology: true,
bufferCommands: false,
// bufferMaxEntries: 0,
// useFindAndModify: false,
// useCreateIndex: true,
}
cached.promise = mongoose.connect(process.env.MONGODB_URL, opts).then((mongoose) => {
return mongoose
})
}
cached.conn = await cached.promise
return cached.conn
}
export default dbConnect
因此,在通过代码进行任何与数据库相关的查询之前,我会调用await dbConnect()。它工作正常。
但是为了在数据库中存储会话,在 NextAuth 中,我无法使用上述功能。所以为此,我正在使用这个自定义代码(/lib/mongodb.js):
/**
*
* Used only for Next-Auth
*
*/
import { MongoClient } from "mongodb"
const uri = process.env.MONGODB_URL
const options = {
useUnifiedTopology: true,
useNewUrlParser: true,
}
let client
let clientPromise
if (!process.env.MONGODB_URL) {
throw new Error("Please add your Mongo URI to .env.local")
}
if (process.env.NODE_ENV === "development") {
// In development mode, use a global variable so that the value
// is preserved across module reloads caused by HMR (Hot Module Replacement).
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options)
global._mongoClientPromise = client.connect()
}
clientPromise = global._mongoClientPromise
} else {
// In production mode, it's best to not use a global variable.
client = new MongoClient(uri, options)
clientPromise = client.connect()
}
// Export a module-scoped MongoClient promise. By doing this in a
// separate module, the client can be shared across functions.
export default clientPromise
而我的 /pages/api/auth/[...nextauth].js 中的代码是这样的:
import NextAuth from 'next-auth'
import { MongoDBAdapter } from "@next-auth/mongodb-adapter"
import mongodb from '../../../lib/mongodb'
//...
export default async function auth(req, res) {
return await NextAuth(req, res, {
//....
adapter: MongoDBAdapter({
db: (await mongodb).db("my_db_name_here")
}),
//....
})
}
这是正在使用的包:
"mongodb": "^4.1.2",
"mongoose": "^6.0.1",
"next": "11.0.1",
"next-auth": "^4.0.0-beta.6",
"react": "17.0.2",
"react-dom": "17.0.2",
问题是,我有时会收到如下电子邮件通知:
我的网站仍处于测试阶段(仅由两个人测试)并托管在 Vercel 服务器中。我相信这可能是因为 NextAuth 每次都在创建新的数据库连接?对出了什么问题有任何想法吗?
【问题讨论】:
标签: mongodb next.js mongodb-atlas vercel next-auth