You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AdonisJS和Mongoose连接MongoDB时认证失败求助

AdonisJS + Mongoose 连接MongoDB认证失败问题解决建议

错误原因分析

错误码18 (AuthenticationFailed)明确指向MongoDB认证环节失败,常见原因包括:连接字符串未指定认证源、用户权限不足、代码连接逻辑不合理。

具体修改建议

1. 修正MongoDB连接字符串

默认情况下MongoDB的root用户创建在admin数据库下,连接时必须指定认证源,否则会在目标库(todo)中查找用户导致失败。修改连接字符串:

const MONGOURI = 'mongodb://root:1234@localhost:27017/todo?authSource=admin';

如果是MongoDB 4.0+版本,可强制使用更安全的SCRAM认证机制:

const MONGOURI = 'mongodb://root:1234@localhost:27017/todo?authSource=admin&authMechanism=SCRAM-SHA-256';

2. 重构数据库连接逻辑(避免重复连接)

原代码在控制器构造函数中初始化连接,会导致每次请求都创建新连接,既浪费资源又可能引发异常。AdonisJS推荐用服务提供者统一管理数据库连接:

创建Mongoose服务提供者(app/Providers/MongooseProvider.ts)

import type { ApplicationContract } from '@ioc:Adonis/Core/Application'
import mongoose from 'mongoose'

export default class MongooseProvider {
  constructor(protected app: ApplicationContract) {}

  // 应用启动时初始化连接
  public async boot() {
    // 建议将连接字符串配置到config/database.ts,避免硬编码
    const mongoUri = this.app.config.get('database.mongoUri')
    try {
      await mongoose.connect(mongoUri)
      console.log('✅ MongoDB连接成功')
    } catch (error) {
      console.error('❌ MongoDB连接失败:', error)
      process.exit(1)
    }
  }

  // 应用关闭时断开连接
  public async shutdown() {
    await mongoose.disconnect()
    console.log('🔌 MongoDB已断开连接')
  }
}

在start/app.ts中注册提供者

providers: [
  // ...其他默认提供者
  () => import('App/Providers/MongooseProvider'),
]

3. 独立定义Mongoose模型(避免重复定义)

原代码在index方法中每次请求都重新创建模型,会触发Mongoose重复定义的警告。将模型单独抽离:

创建Task模型(app/Models/Task.ts)

import mongoose, { Schema, Model } from 'mongoose'

// 定义文档类型接口
interface TaskDocument extends mongoose.Document {
  name: string
  description: string
}

// 定义Schema
const TaskSchema = new Schema<TaskDocument>({
  name: { type: String, required: true },
  description: String
})

// 导出模型
const Task: Model<TaskDocument> = mongoose.model<TaskDocument>('Task', TaskSchema)

export default Task

4. 简化控制器代码

'use strict'

import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Task from 'App/Models/Task'

export default class TasksController {
  public async index ({ response }: HttpContextContract) {
    try {
      // 创建任务
      const task = new Task({
        name: Math.random().toString(36).substring(7),
        description: "This is description of the task."
      })
      await task.save()

      // 查询所有任务
      const tasks = await Task.find()
      return response.json(tasks)
    } catch (error) {
      return response.status(500).json({ error: error.message })
    }
  } 
}

5. 验证MongoDB用户权限(可选)

如果修改连接字符串后仍失败,确认root用户拥有todo数据库的读写权限,或创建专用用户:

# 进入MongoDB shell
mongo
# 认证root用户
use admin
db.auth('root', '1234')
# 切换到todo数据库
use todo
# 创建专用用户
db.createUser({
  user: 'todo_user',
  pwd: 'your_secure_password',
  roles: [{ role: 'readWrite', db: 'todo' }]
})

此时连接字符串改为:

const MONGOURI = 'mongodb://todo_user:your_secure_password@localhost:27017/todo?authSource=todo';

内容的提问来源于stack exchange,提问作者Chris Dean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:55:20