Search code examples
node.jsmongodb

How to authenticate into Mongodb using Node JS driver


I already have created a user that has the proper roles to readWrite the database following this tutorial https://www.cyberciti.biz/faq/how-to-secure-mongodb-nosql-production-database/. I can login to the user using my username and password from both the command line (mongosh) and using the GUI (mongodb compass). However I can't figure out how to authenticate using Node JS. Every time I try it says

MongoServerError: Authentication failed.
  ...
  ok: 0,
  code: 18,
  codeName: "AuthenticationFailed",
  connectionGeneration: 0

My current code is based on the Mongodb docs https://www.mongodb.com/docs/drivers/node/current/fundamentals/authentication/mechanisms/

const { MongoClient } = require("mongodb");
const myMongo = new MongoClient(`mongodb://${encodeURIComponent(username)}:${encodeURIComponent(password)}@localhost:27017`);
myMongo.connect();

The encodeURIComponent is necessary to avoid MongoParseError: Password contains unescaped characters. All examples on Google of how to do this use mongoose or some other wrapper library, but I don't want to use a wrapper. I've tried specifiying the authMechanism but it changes nothing. The rest of the URL is correct because it worked before I setup authentication. The username and password are also correct because they work in both mongosh and compass. The only do not work in Node JS.

Here is my package.json

{
  "name": "vxsacademy",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "cd src; node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "GPL-3.0",
  "dependencies": {
    "@types/node": "^18.0.6",
    "bson": "^6.1.0",
    "crypto-js": "^4.1.1",
    "mongodb": "^6.1.0"
  }
}

Solution

  • I got it working. Had to create an admin user in mongosh, create another user that has access to the db, and then use the following code to connect to the db

    const secrets = {
        MONGO_PORT: 27017,
        MONGO_IP: "localhost",
        MONGO_PASSWORD: "password123"
    };
    
    let myMongo;
    if (secrets.MONGO_PASSWORD) {
        myMongo = new MongoClient(`mongodb://vxsacademyuser:${secrets.MONGO_PASSWORD}@${secrets.MONGO_IP}:${secrets.MONGO_PORT}/?authSource=vxsacademy`);
    } else {
        console.log("WARNING: MongoDB is running without authentication");
        myMongo = new MongoClient(`mongodb://${secrets.MONGO_IP}:${secrets.MONGO_PORT}`);
    }
    
    await myMongo.connect();
        
    db = myMongo.db("vxsacademy");
    

    This differs from the above answer that doesn't work because this uses ?authSource=vxsacademy rather than ?authMechanism=DEFAULT