denodrivers / mongo

🍃 MongoDB driver for Deno 🦕
https://deno.land/x/mongo
MIT License
509 stars 95 forks source link

Unable to connect to mongodb Atlas #319

Open playerx opened 2 years ago

playerx commented 2 years ago

Hey, it works with local db but fails with mongodb atlas connection string, I'm using the syntax like this:

await client.connect(
    "mongodb+srv://user:password@name.mongodb.net/db?authMechanism=SCRAM-SHA-1"
);

// also tried this

await client.connect(
    "mongodb+srv://user:password@name.mongodb.net/db?retryWrites=true&w=majority&authMechanism=SCRAM-SHA-1"
);

// and this

await client.connect(
    "mongodb+srv://user:password@name.mongodb.net/db?retryWrites=true&w=majority"
);

It always fails here: https://deno.land/x/mongo@v0.29.0/src/client.ts#L41 with error:

{
"ok":0,
"errmsg":"Authentication failed.",
"code":18,
"codeName":"AuthenticationFailed",
"$clusterTime":{"clusterTime":{"$timestamp":"7043035952079437828"},"signature":{"hash":"z8hkCMby/OYpTnJXHNS7+rZfBvI=","keyId":{"high":1625418439,"low":1,"unsigned":false}}},
"operationTime":{"$timestamp":"7043035952079437828"}
}

Can you share if it's a known issue or do I need to provide some additional params?

erfanium commented 2 years ago

https://github.com/erfanium/deno-deploy-mongo this demo uses MongoDB Atlas for its database with no problem. do you use any non-default options when you creating a database?

This issue needs a reproduction steps for me

playerx commented 2 years ago

I've a simple script like this:

import { MongoClient } from "https://deno.land/x/mongo@v0.29.0/mod.ts";

const client = new MongoClient();

const db = await client.connect(
  "mongodb+srv://USER:PASSWORD@jok-prod.RANDOM.mongodb.net/jok?authMechanism=SCRAM-SHA-1"
);

const names = await db.listCollectionNames();

console.log(names);

and it fails, I've tried the same script on different mongo atlas clusters and had the same error.

Can you share the structure of the connection string you are using? Maybe I miss something there

playerx commented 2 years ago

Ah it seems the database name in the connection string isn't supported for now. It started working once I've updated connection string like this:

 "mongodb+srv://USER:PASSWORD@jok-prod.RANDOM.mongodb.net/?authMechanism=SCRAM-SHA-1"
erfanium commented 2 years ago

are you sure? maybe you should use authSource property

playerx commented 2 years ago

I've tried calling parse function for the connectionString I was using and here is the result:

Input:

 "mongodb+srv://USER:PASSWORD@jok-prod.RANDOM.mongodb.net/jok?authMechanism=SCRAM-SHA-1"

Output:

{
  servers: [
    { host: "jok-prod-shard-00-01.RAND.mongodb.net.", port: 27017 },
    { host: "jok-prod-shard-00-02.RAND.mongodb.net.", port: 27017 },
    { host: "jok-prod-shard-00-00.RAND.mongodb.net.", port: 27017 }
  ],
  authSource: "admin",
  replicaSet: "atlas-132kf5-shard-0",
  db: "jok",
  credential: {
    username: "USER",
    password: "PASSWORD",
    db: "jok",
    mechanism: "SCRAM-SHA-1"
  },
  compression: [],
  tls: true,
  retryWrites: true
}

As you can see it changed credentials database as well and that's the issue here I think

erfanium commented 2 years ago

i think that's an expected behavior, just use something like: mongodb+srv://USER:PASSWORD@jok-prod.RANDOM.mongodb.net/jok?authMechanism=SCRAM-SHA-1&authSource=admin

playerx commented 2 years ago

The reason why I think it's an issue is that the connection string I used works properly with nodejs mongo (official) driver and many users will use the same connections string and had the same issue.

I think credential.db should not be changed unless there will be provided authSource explicitly.