With this help, I created a super user in the mongo shell: Create Superuser in mongo
user: "try1"
passw: "hello"
In mongo cmd, I have 3 databases: 'admin', 'myDatabase' and 'local'.
Now I try to use this authorized connection to the database called 'myDatabase'.
mongoose.connect('mongodb://try1:hello#localhost:27017/myDatabase');
But this is the error I get:
name: 'MongoError',
message: 'Authentication failed.',
ok: 0,
errmsg: 'Authentication failed.',
code: 18,
codeName: 'AuthenticationFailed' }
Mongoose disconnected
Mongoose disconnected through ${msg}
I had the same problem many hours ago, and after all I solve it. My code is:
mongoose.createConnection(
"mongodb://localhost:27017/dbName",
{
"auth": {
"authSource": "admin"
},
"user": "admin",
"pass": "password"
}
);
Further to #kartGIS, I've added one more option to make the connection code perfect as possible.
mongoose.connect("mongodb://localhost:27017/databaseName", {
"auth": { "authSource": "admin" },
"user": "username",
"pass": "password",
"useMongoClient": true
});
This is the correct answer now. others are not completely correct.
await mongoose.connect("mongodb://localhost:27017/db", {
poolSize: 10,
authSource: "admin",
user: "admin",
pass: "password",
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
});
Syntax:
await mongoose.connect('mongodb://username:password#host:port/database?authSource=admin');
Example:
await mongoose.connect('mongodb://myUser:myPassword#localhost:27017/myDataBase?authSource=admin');
Working fine for me on Mongodb 4.2 and Mongoose 5.7.13
Node.js
const Connect = async () => {
let url = "mongodb://localhost:27017/test_db";
try {
let client = await Mongoose.connect( url, {
poolSize: 10,
authSource: "admin",
user: "root",
pass: "root123",
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true
} );
log( "Database is connected!" );
} catch ( error ) {
log( error.stack );
process.exit( 1 );
}
}
Connect();
/etc/mongod.conf
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
storage:
dbPath: /var/lib/mongo
journal:
enabled: true
processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
net:
port: 27017
bindIp: 0.0.0.0
setParameter:
enableLocalhostAuthBypass: false
security:
authorization: enabled
Database User
use admin;
db.createUser(
{
user: "root",
pwd: "root123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
}
)
show users;
{
"_id": "admin.root",
"userId": UUID( "5db3aafd-b1fd-4bea-925e-8a4bfb709f22" ),
"user": "root",
"db": "admin",
"roles": [ {
"role": "userAdminAnyDatabase",
"db": "admin"
},
{
"role": "readWriteAnyDatabase",
"db": "admin"
}
],
"mechanisms": [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
I have the same problem, and it solved by removing the 'authSource' param
/* Not working */
mongoose.connect("mongodb://localhost:27017/test", {
"auth": { "authSource": "admin" },
"user": "admin",
"pass": "admin123",
"useMongoClient": true
});
/* Working */
mongoose.connect("mongodb://localhost:27017/test", {
"user": "admin",
"pass": "admin123",
"useMongoClient": true
});
Tested on Mongoose-v5.0.0.
THIS ANSWER FOR MONGOOSE 6.7.0! USED IN NUXT 3
.env PART
MONGO_URI = "mongodb://localhost:27017/MyBeautifulDB"
MONGO_USERNAME = "mongoadmin"
MONGO_PASSWORD = "mystrongpassword"
DB CONNECTION PART
import mongoose from 'mongoose';
export default async (_nitroApp) => {
const config = useRuntimeConfig();
mongoose.connect(config.MONGO_URI, {
maxPoolSize: 10,
authSource: "admin",
user: config.MONGO_USERNAME,
pass: config.MONGO_PASSWORD
})
.then(() => console.log('Connected to DB'))
.catch((e) => console.log(e));
}
nuxt.config.ts - Register your db connection file to configuration.
export default defineNuxtConfig({
runtimeConfig: {
MONGO_URI: process.env.MONGO_URI,
},
nitro: {
plugins: ['#/server/db/index.ts']
}
})
I got MongoParseError: credentials must be an object with 'username' and 'password' properties when used above answers.
Add username password to auth object solved the issue
try {
await connect("mongodb://localhost:27017/dbname", {
auth: { username: "root", password: "example" },
authSource: "admin",
});
console.log("Connected to mongo db");
} catch (error) {
console.error("Error connecting to mongodb", error);
}
mongodb version 5.0.2
mongoose 6.0.4
Respectively, if your authSource is the database ('myDB' in the example) itself and you are trying to use the ConnectionOption dbName, you have to match authSource.
await mongoose.connect('mongodb://localhost:27017,' {
dbName: 'myDB',
user: 'myUser',
pass: 'asldjaskdj'
);
Will fail with error:
{
"msg": "Authentication failed",
"attr": {
"mechanism": "SCRAM-SHA-1",
"principalName": "myUser",
"authenticationDatabase": "admin",
"client": "...",
"result": "UserNotFound: Could not find user \"myUser\" for db \"admin\""
}
}
Adding authSource: 'myDB' to the connect options will work. Example:
await mongoose.connect('mongodb://localhost:27017,' {
dbName: 'myDB',
authSource: 'myDB',
user: 'myUser',
pass: 'asldjaskdj'
);
I had the same problem. I am using an older MongoDB instance. I simply added authSource=admin to the connection string and it solved the problem.
According to the latest documentation, it should be like this:
mongoose.connect("mongodb://localhost:27017/databaseName", {
"user": "username",
"pass": "password",
"authSource": "databaseName" // users are scoped to DBs
});
Tested on mongoose6.x.x
works for me. i use local database, and mongoose ver 6.9.1
.env file:
DB_HOST=127.0.0.1:27017
DB_NAME=blabla
DB_USER=blablabla
DB_PWD=blablablabla
js file:
const DB = `mongodb://${process.env.DB_HOST}/${process.env.DB_NAME}`;
mongoose
.connect(DB, {
authSource: 'admin',
user: process.env.DB_USER,
pass: process.env.DB_PWD,
})
.then(() => {
console.log('Connected to database.');
})
.catch((err) => {
console.log(err.message);
});
NOTE
This answer is not answering original question but trying to help people in similar situation using NestJS
NestJS
#Module({
imports: [
MongooseModule.forRoot(
'mongodb://mongo:27017/test',
{
auth: {
username: 'root',
password: 'test',
},
authSource: 'admin',
},
),
],
})
export class AppModule {}
I also faced the same issue but resolved it with this
mongoose.connect(mongodb://${dbUser}:${dbPwd}#${dbHost}:${dbPort}/userInfo?authSource=admin). Assuming you have the authentication setup in mongodb.
Related
A strapi API app connects and works perfectly on SQLlite. however we need it to connect to SQL Express db. the msssql module is installed through npm i mssql and the connection strings have been amended in order to connect to mssql heres the config file
/*
const fs = require( "fs" );
module.exports = ( { env } ) => ( {
defaultConnection: 'default',
connections: {
default: {
connector: 'bookshelf',
settings: {
client: 'sqlite',
filename: env( 'DATABASE_FILENAME', '.tmp/data.db' ),
},
options: {
useNullAsDefault: true,
},
},
},
} );
*/
const sql = require('mssql')
module.exports = ( { env } ) => ( {
defaultConnection: 'default',
connections: {
default: {
connector: 'mssql',
settings: {
user: "***",//process.env.DB_USER,
password: "***",//process.env.DB_PWD,
database: "***",//process.env.DB_NAME,
server: "**.**.**.**",
port: 1433,
connectionTimeOut: 150000,
pool: {
max: 10,
min: 0,
idleTimeoutMillis: 30000
},
options: {
enableArithAbort: true,
encrypt: false,
trustedConnection: true
},
useNullAsDefault: true
}
}
}
})
the command lines commended out (for the code above) is the previous connection to sql lite that works.
now the error message is the following:
PS C:*Team\Q*_Team\AngularAPI\ui\molla-angular\strapi> npm start
mollastrapi#0.1.0 start
strapi start
[2022-07-29T08:05:53.028Z] debug ⛔️ Server wasn't able to start properly.
[2022-07-29T08:05:53.029Z] error TypeError: requireConnector(...) is not a function
at Object.load (C:\****Team\Q****_Team\AngularAPI\ui\molla-
angular\strapi\node_modules\strapi-database\lib\connector-registry.js:20:65)
at DatabaseManager.initialize (C:\****Team\Q****_Team\AngularAPI\ui\molla-
angular\strapi\node_modules\strapi-database\lib\database-manager.js:32:21)
at Strapi.load (C:\****Team\Q****_Team\AngularAPI\ui\molla-
angular\strapi\node_modules\strapi\lib\Strapi.js:297:19)
at async Strapi.start (C:\****Team\Q***_Team\AngularAPI\ui\molla-
angular\strapi\node_modules\strapi\lib\Strapi.js:156:9)
PS C:\****Team\Q****_Team\AngularAPI\ui\molla-angular\strapi>
I'm newbie to typeorm and trying to create a connection to db. I read the typeorm's doc and found this code, it uses DataSource to create connection:
import "reflect-metadata"
import { DataSource } from "typeorm"
import { Photo } from "./entity/Photo"
const AppDataSource = new DataSource({
type: "postgres",
host: "localhost",
port: 5432,
username: "root",
password: "admin",
database: "test",
entities: [Photo],
synchronize: true,
logging: false,
})
AppDataSource.initialize()
.then(() => {
// here you can start to work with your database
})
.catch((error) => console.log(error))
But when searching for some references in other sources, they use createConnection instead:
import { createConnection } from "typeorm"
createConnection({
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "mysql",
database: "mysql",
entities: [
__dirname + "/entity/*.ts"
],
synchronize: true,
logging: false
}).then(async connection => {
…
…
}).catch(error => console.log(error));
I'm a bit confused. What approach should I use for creating connection to db between those two above?
For the next person that comes across this issue, createConnection has been deprecated in favor of using new DataSource. See here:
https://typeorm.io/changelog#030httpsgithubcomtypeormtypeormpull8616-2022-03-17
When I try to query using repository for login api, I receive this error
QueryFailedError: relation "user" does not exist
After debuging, I realize the nestjs still using database with name "postgres". eventhough I set my database name in my .env as "nestjs". (I can confirm because when I migrate and seed the database "postgres" the login function works)
DB_TYPE=postgres
DB_HOST=db
DB_USER=postgres
DB_PASS=postgres
DB_NAME=nestjs
DB_NAME_TEST=nestjs_test
DB_PORT=5432
All my migration and seed process already using database "nestjs". Below is my files to configure my database connection
configuration.ts
import { registerAs } from '#nestjs/config';
export default registerAs('database', () => ({
type: process.env.DB_TYPE,
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
name: process.env.DB_NAME,
nameTest: process.env.DB_NAME_TEST,
port: process.env.DB_PORT,
}));
database/config.service.ts
...
get name(): string {
return this.configService.get<string>(
this.configService.get<string>('app.env') === 'test'
? 'database.nameTest'
: 'database.name',
);
}
...
database/config.migration.ts
import { SnakeNamingStrategy } from 'typeorm-naming-strategies';
export = {
type: process.env.DB_TYPE,
host: process.env.DB_HOST,
port: +process.env.DB_PORT,
username: process.env.DB_USER,
password: process.env.DB_PASS,
database:
process.env.NODE_ENV === 'test'
? process.env.DB_NAME_TEST
: process.env.DB_NAME,
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
migrations: [__dirname + '/../../database/migrations/*{.ts,.js}'],
cli: {
migrationsDir: __dirname + '/../../database/migrations',
},
extra: {
charset: 'utf8mb4_unicode_ci',
},
synchronize: false,
logging: true,
keepConnectionAlive: true,
namingStrategy: new SnakeNamingStrategy(),
};
database/provider.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule, TypeOrmModuleOptions } from '#nestjs/typeorm';
import { SnakeNamingStrategy } from 'typeorm-naming-strategies';
import { DatabaseConfigModule } from '../../config/database/config.module';
import { DatabaseConfigService } from '../../config/database/config.service';
#Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [DatabaseConfigModule],
inject: [DatabaseConfigService],
useFactory: async (
service: DatabaseConfigService,
): Promise<TypeOrmModuleOptions> => ({
type: service.type,
host: service.host,
port: service.port,
username: service.user,
password: service.password,
name: service.name,
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
migrations: [__dirname + '/../../database/migrations/*{.ts,.js}'],
cli: {
migrationsDir: __dirname + '/../../database/migrations',
},
extra: {
charset: 'utf8mb4_unicode_ci',
},
synchronize: false,
logging: true,
keepConnectionAlive: true,
namingStrategy: new SnakeNamingStrategy(),
}),
}),
],
})
export class DatabaseProviderModule {}
And here is my databases:
If you guys need more file for information please let me know. I'm new to nestjs and typeorm, So please tell me what's wrong with my code. Thank you!
TypeormModule has the database property which provides the database name. You are using name in provider.module.ts:
Wrong name : databaseName
Right database : databaseName
TypeOrmModule.forRootAsync({
useFactory: () => ({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
});
currently i'am using tedious package to connect to the database and do operations but i would like to switch to node-mssql (seems less messy).
The problem i'm getting is connection timeout:
originalError: ConnectionError: Failed to connect to yyy:1433 in 15000ms
code: 'ETIMEOUT',
isTransient: undefined
}
My config with tedious :
const config = {
server: process.env.HOST, // update me
authentication: {
type: 'default',
options: {
userName: process.env.USER, // update me
password: process.env.PASS, // update me
},
},
options: {
// If you are on Microsoft Azure, you need encryption:
database: process.env.DB,
rowCollectionOnDone: true, // update me
},
};
My config with mssql :
const configMssql = {
user: process.env.USER,
password: process.env.PASS,
server: process.env.HOST, // update me
database: process.env.DB,
pool: {
max: 10,
min: 0,
idleTimeoutMillis: 30000,
},
options: {
encrypt: false, // for azure
trustServerCertificate: false, // change to true for local dev / self-signed certs
},
};
or
const configMssqlString = `Server=${process.env.HOST},1433;Database=${process.env.DB};User Id=${process.env.USER};Password=${process.env.PASS};Encrypt=false`;
Can't figure out whats wrong
Connecting to my my DigitalOcean database with Sequelize works fine when I'm not migrating. For example, attempting to create a new table works just fine; the code below successfully connects and creates a new table.
sequelize = new Sequelize(config.use_env_variable, config);
sequelize.authenticate().then(console.log('success')).catch((error) => console.log(error));
sequelize.define('test-table', {
test_id: {
type: Sequelize.INTEGER,
},
});
sequelize.sync();
I have a CA certificate .crt file I downloaded from DigitalOcean that I'm passing in with the Sequelize options. My config.js looks like
development: {
use_env_variable: 'postgresql://[digitalocean_host_url]?sslmode=require',
ssl: true,
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false,
ca: fs.readFileSync(`${__dirname}/../.postgresql/root.crt`),
},
},
},
However when I try to create tables using migrations with
npx sequelize-cli db:migrate
I receive the following output and error:
Parsed url postgresql://[digitalocean_host_url]?sslmode=require
ERROR: no pg_hba.conf entry for host [host], user [user], database [database], SSL off
Which is very strange, because SSL is working when I create a table using just Sequelize sync. I have a .sequelizerc file for the sequelize-cli configurations, which looks like this:
const path = require('path');
const env = process.env.NODE_ENV || 'development'
const config = require('./config/config')[env];
module.exports = {
'config': path.resolve('config', 'config.js'),
'url': config.use_env_variable,
'options-path': path.resolve('config', 'sql-options.json')
}
inside my sql-options.json I have the following
{
"use_env_variable": "postgresql://[digitalocean_host_url]?sslmode=require",
"dialect":"postgres",
"ssl": true,
"dialectOptions": {
"ssl": {
"required": true,
"rejectUnauthorized": true,
"ca": "/../.postgresql/root.crt"
}
}
}
I've tried a lot of the advice from various resources, including the sequelize/cli repo. But none of it seems to work. Any advice would be helpful.
I had the same issue and the fix was to add the code below in the migrations config file even though you already have it in the database connection file.
The following code is in the config/config.js file for migrations.
production: {
username: ****,
password: ****,
database: ****,
host: ****,
dialect: ****,
port: ****,
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false,
},
},
},
This is how my DB connection looks like that was working normally.
const sequelize = new Sequelize({
host: ****,
database: ****,
username: ****,
password: ****,
dialect: ****,
port: ****,
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false,
},
},
});