Почему возникает ошибка Failed Auth при подключении сервера fastify ко второму кластеру mongoDB?

Я пытаюсь добавить соединение с базой данных на сервер fastify по разным причинам, это сценарий, и есть два отдельных mongodb, к которым необходимо подключиться.

index.js:

'use strict'

const dotenv = require('dotenv');
dotenv.config();

const path = require('path');
const tunnel = require('tunnel-ssh');
const Autoload = require('fastify-autoload');
const fastifyMongoose = require('fastify-mongoose-driver');
const fastify = require('fastify');
const { runTasks } = require('./taskRunner.js')
const { connectPerformanceDB } = require('./performanceDB.js')

const fastifyServer = fastify({ logger: process.env.DEVELOPMENT });

const User = require('./schemas/User');
const Promo = require('./schemas/Promo');
const Result = require('./schemas/PageSpeedResult')

fastifyServer.register(Autoload, { dir: path.join(__dirname, 'routes') });

const tunnelConfig = {
  username: '*****',
  host: '*****.com',
  privateKey: require('fs').readFileSync('../../.ssh/id_rsa'),
  srcPort: 27017,
  dstPort: 27017
};

tunnel(tunnelConfig, error => {

  if (error) console.log('SSH connection error: ', + error);

  fastifyServer.register(fastifyMongoose, {
    uri: process.env.MONGO_CONNECTION_STRING,
    settings: {
      user: '*************',
      pass: '*************',
      useNewUrlParser: true,
      useCreateIndex: true,
      useUnifiedTopology: true,
      config: {
        autoIndex: true
      }
    },
    models: [User, Promo],
    useNameAndAlias: true
  });

  fastifyServer.register(fastifyMongoose, {
    uri: process.env.PERFORMANCE_DB_CONNECTION_STRING, 
    settings: {
      user: '******',
      pass: '**********',
      useNewUrlParser: true,
      useCreateIndex: true,
      useUnifiedTopology: true,
      config: {
        autoIndex: true
      }
    },
    models: [Result],
    useNameAndAlias: true
  })

  fastifyServer.listen(process.env.PORT, (err, address) => {

    if (err) throw err;

    fastifyServer.log.info(`server listening on ${address}`);
  });
});

Проблема, с которой я сталкиваюсь, заключается в том, что этот текущий код выдает ошибки следующим образом:

index.js:102
    if (err) throw err;
             ^

MongoError: Authentication failed.

строка, в которой он ошибается, является оператором if внутри этого блока:

fastifyServer.listen(process.env.PORT, (err, address) => {
    
   if (err) throw err;
    
   fastifyServer.log.info(`server listening on ${address}`);
});

Подтвержденный пользователь, пароль и база данных верны.

константа uri для подключения выглядит так: mongodb://localhost/<name_of_cluster>, также пробовали строку подключения, указанную в веб-приложении mongo на вкладке подключения.

Любые предложения по неудачной ошибке аутентификации или внедрению второго кластера БД с помощью fastify?

ОБНОВЛЕНИЕ: я пробовал несколько строк подключения. как упомянутый в посте, так и mongodb://<username>:<pass>@pagespeedinsights-hjdvp.mongodb.net/<database>?retryWrites=true&w=majority и mongodb+srv://<username>:<pass>@pagespeedinsights-hjdvp.mongodb.net/<database>?retryWrites=true&w=majority

первые ошибки на сервере с:

Error: getaddrinfo ENOTFOUND pagespeedinsights-hjdvp.mongodb.net

вторые ошибки (из той же строки, что и исходная строка выше) на сервере с:

index.js:102
    if (err) throw err;
             ^

TypeError: schema[key].forEach is not a function

person Jim    schedule 22.06.2020    source источник
comment
Посмотрите в журнале ошибок сервера.   -  person D. SM    schedule 23.06.2020
comment
@D.SM, упомянутая ошибка взята из журнала ошибок сервера.   -  person Jim    schedule 23.06.2020
comment
так как журналы говорят MongoError: Authentication failed., вы пытались установить аутентификацию в uri? mongodb://user:password@localhost/dbName   -  person Manuel Spigolon    schedule 23.06.2020
comment
@ManuelSpigolon пробовал несколько строк подключения. как упомянутый в посте, так и mongodb://<username>:<pass>@pagespeedinsights-hjdvp.mongodb.net/<database>?retryWrites=true&w=majority и mongodb+srv://<username>:<pass>@pagespeedinsights-hjdvp.mongodb.net/<database>?retryWrites=true&w=majority   -  person Jim    schedule 23.06.2020
comment
Не могли бы вы попробовать зарегистрировать только один fastifyMongoose? Я подозреваю, что плагин не поддерживает множественные регистрации.   -  person Manuel Spigolon    schedule 23.06.2020
comment
@ManuelSpigolon да, работает только один зарегистрированный кластер базы данных. но мне нужно два   -  person Jim    schedule 23.06.2020
comment
Хорошо, у меня проблема. Нужно ли вашим обработчикам использовать оба Mongo или для некоторых маршрутов нужен первый, а для других маршрутов нужен второй?   -  person Manuel Spigolon    schedule 23.06.2020
comment
мы отказались от использования мангуста fastify, в любом случае спасибо @ManuelSpigolon   -  person Jim    schedule 23.06.2020


Ответы (1)


Проблема зависит от плагина require('fastify-mongoose-driver'), так как эта строка выполняется каждый раз, когда вы регистрируете этот плагин:

await mongoose.connect(uri, settings);

здесь исходный код

Таким образом, этот плагин использует синглтон в качестве соединения для каждой регистрации, переопределяя первые.

Вот что происходит под капотом:

const mongoose = require('mongoose')

// docker run -d -p 27018:27017 --rm -e MONGO_INITDB_ROOT_USERNAME=adminOne -e MONGO_INITDB_ROOT_PASSWORD=password --name mongoOne mongo:4
// docker run -d -p 27019:27017 --rm -e MONGO_INITDB_ROOT_USERNAME=adminTwo -e MONGO_INITDB_ROOT_PASSWORD=password --name mongoTwo mongo:4

;(async function () {
  await mongoose.connect('mongodb://adminOne:password@localhost:27018')
  console.log('connected 1')

  await mongoose.connect('mongodb://adminTwo:password@localhost:27019')
  console.log('connected 2')

  const kittySchema = new mongoose.Schema({ name: String })
  const Kitten = mongoose.model('Kitten', kittySchema)

  // it will be saved on second connection

  const silence = new Kitten({ name: 'Silence' })
  silence.save(function (err, fluffy) {
    if (err) return console.error(err)
    console.log(fluffy)
  })
})()

И это воссоздает ту же ошибку, что и у вас:

const fastify = require('fastify')()

fastify.register(require('fastify-mongoose-driver').plugin,
  {
    uri: 'mongodb://adminOne:password@localhost:27018',
    settings: {
      useNewUrlParser: true,
      config: { autoIndex: true }
    },
    models: [{ name: 'Kittens', schema: { name: String } }]
  }
)

fastify.register(require('fastify-mongoose-driver').plugin,
  {
    uri: 'mongodb://adminTwo:password@localhost:27019',
    settings: {
      useNewUrlParser: true,
      config: { autoIndex: true }
    },
    models: [{ name: 'Dogs', schema: { name: String } }]
  }
)

fastify.ready(err => {
  console.log(err) // TypeError: schema[key].forEach is not a function
})

Вам следует использовать конфигурации многократных соединений mongoose для архивации ваших потребностей и реализации/или ожидания и обновить этот плагин для поддержки этой функции.

person Manuel Spigolon    schedule 25.06.2020