Ошибка аутентификации мангуста с помощью mongodb внутри службы докеров

#node.js #mongodb #docker #mongoose

Вопрос:

Итак, вот что я пытаюсь сделать. Я создал службу MongoDB с помощью docker и пытаюсь подключить свой проект NodeJS к службе базы данных с помощью мангуста. Вот мой docker-compose.yaml

 version: '3'

services:

  mongodb:
    container_name: mongo_database
    image: mongo
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=password
    networks:
      - mongo-compose-network
    ports:
      - '27017:27017'

  mongo-express:
    container_name: mongo_express
    image: mongo-express
    restart: unless-stopped
    depends_on:
      mongodb:
        condition: service_started
    networks:
      - mongo-compose-network
    environment:
      - ME_CONFIG_MONGODB_ADMINUSERNAME=admin
      - ME_CONFIG_MONGODB_ADMINPASSWORD=password
      - ME_CONFIG_MONGODB_SERVER=mongodb
    ports:
      - '8081:8081'

networks:
  mongo-compose-network:
    driver: bridge
 

Я открыл панель mongo-express, и все работает нормально. Теперь вот мое приложение NodeJS, используемое MongoClient для подключения к базе данных и вставки фиктивной записи.

 require('dotenv').config();

// required modules
const mongoose          = require("mongoose")
const MongoClient       = require('mongodb').MongoClient;

// database config
const db_name           = process.env.DB_NAME || "office"
const mongoUrl          = process.env.MONGO_URL || `mongodb://admin:password@localhost:27017`
const mongooseUrl       = process.env.MONGO_URL || `${mongoUrl}/${db_name}`


// database connection and sample document

const connectOptions    = {  useNewUrlParser: true,  useUnifiedTopology: true }

const document = {
    "name": "John Doe",
    "employee_id": Math.floor(Math.random() * 1000)
}

MongoClient.connect(mongoUrl, connectOptions).then((client)=> {

    client.db(db_name).collection("users").insertOne(document).then(()=> {
        console.log("Document Inserted")
        process.exit(1)
    })

}).catch((e) => {

    console.log(`Cannot connect to the database: ${e.message}`)
    process.exit(1)

})
 

Все по — прежнему в порядке. Приложение успешно вставило запись в базу данных mongo. Однако все не работает, когда я пытался использовать Mongoose вместо MongoClient этого . Вот мой фрагмент кода для Mongoose .

 require('dotenv').config();

// required modules
const mongoose          = require("mongoose")
const MongoClient       = require('mongodb').MongoClient;

// database config
const db_name           = process.env.DB_NAME || "office"
const mongoUrl          = process.env.MONGO_URL || `mongodb://admin:password@localhost:27017`
const mongooseUrl       = process.env.MONGO_URL || `${mongoUrl}/${db_name}`


// database connection and sample document

const connectOptions    = {  useNewUrlParser: true,  useUnifiedTopology: true }

const document = {
    "name": "John Doe",
    "employee_id": Math.floor(Math.random() * 1000)
}


mongoose.connect(mongooseUrl, connectOptions).then((connection) => {

    connection.collection('users').insert(document);

}).catch((e) => {

    console.log(`Cannot connect to the database: ${e.message}`)
    process.exit(1)

})
 

Это приводит меня к ошибке Cannot connect to the database: Authentication failed. . Есть какие-нибудь идеи о том, как решить эту проблему?

Пожалуйста, обратите внимание: я запускаю приложение node на своей физической машине, а не внутри контейнера, используя изображение. Я попытался localhost:27017 заменить его именем службы, например, mongodb://admin:password@mongodb/office но это тоже не работает. Он возвращает следующую ошибку Cannot connect to the database: getaddrinfo EAI_AGAIN mongodb

Комментарии:

1. Что говорят журналы mongo о неудачной аутентификации?

2. Есть идеи, где я могу найти эти журналы?

3. docker logs mongodb =)

4. Вот журнал из docker MongoDB — pastebin.com/raw/zctjbQLG

5. А, вот этот. Пожалуйста, добавьте «?authSource=администратор» в URL мангуста: mongoosejs.com/docs/connections.html#connection-string-options Монго недавно изменил формат URL-адреса. Часть пути URL — адреса обычно была именем базы данных, но, начиная с версии 4, это имя базы данных аутентификации. Контейнер создает пользователя в admin базе данных, и собственный клиент использует его по умолчанию. В URL Мангуста вы добавили ${db_name} . Ошибка в журналах немного более ясна: Could not find user "admin" for db "office"

Ответ №1:

TL;DR вам необходимо указать базу данных аутентификации в mongooseUrl как ?authSource=admin или как {authSource:"admin"} в connectOptions .

Объяснения

Образ docker регистрирует MONGO_INITDB_ROOT_USERNAME пользователя в базе данных аутентификации по умолчанию admin .

Эта база данных используется по умолчанию, если не указано в URI. На мой вкус, логика излишне сложна, и документация об этом недостаточно ясна:

/defaultauthdb

Необязательный. База данных аутентификации для использования, если строка подключения содержит имя пользователя:пароль@ учетные данные для аутентификации, но параметр authSource не указан.

Если и authSource, и defaultauthdb не указаны, клиент попытается аутентифицировать указанного пользователя в базе данных администратора.

Недостающий бит заключается в том, что /defaultauthdb раньше /database эта версия оставалась в документации мангуста.

Параметр служит 2 целям, и это вызывает путаницу. В нем указывается база данных по умолчанию, в которой вы храните свои коллекции, и база данных проверки подлинности по умолчанию, в которой Mongo ищет пользователей. Значения по умолчанию могут быть перезаписаны параметрами URI:

Источник аутентификации — База данных, используемая при аутентификации с пользователем и передаче. В MongoDB пользователи привязаны к базе данных. Если вы получаете неожиданный сбой входа в систему, вам может потребоваться установить эту опцию.

Или параметры подключения:

Имя базы данных — Указывает, к какой базе данных подключаться, и переопределяет любую базу данных, указанную в строке подключения. Это полезно, если вы не можете указать базу данных по умолчанию в строке подключения, как с некоторыми

Источник аутентификации — База данных, используемая при аутентификации с пользователем и передаче. В MongoDB пользователи привязаны к базе данных. Если вы получаете неожиданный сбой входа в систему, вам может потребоваться установить эту опцию.