122

I'm trying to connect to a MongoDB database with a username and password using Mongoose in Node.js. All the docs say that the connection string should look like

  mongodb://username:password@host:port/db

However, the password contains the '@' character in it. How can I make a connection string out of this that mongoose will understand? Can I escape the '@' in the password or is there another method of connecting I have to use?

Amol M Kulkarni
  • 21,143
  • 34
  • 120
  • 164
iZ.
  • 4,951
  • 5
  • 23
  • 16
  • Have you tried it? Maybe it uses the last @ it finds. – Alex Turpin Sep 20 '11 at 14:20
  • 1
    Nope - doesn't work. Enoding them a %40 doesn't work either. – iZ. Sep 20 '11 at 14:31
  • 4
    I would recommend to change the password to one that does not include @ character. – Sylvain Defresne Sep 20 '11 at 14:39
  • Yes, that would work but I'd love to see a real solution. – iZ. Sep 20 '11 at 14:59
  • 1
    does escaping with a slash work ? "\@" ? – DhruvPathak Sep 21 '11 at 08:18
  • No, that generates an illegal character error. – iZ. Sep 21 '11 at 16:57
  • @SylvainDefresne There will be no '@' character in the password. Its the format of structuring the URL for connecting MongoDB using Mongoose Connection object.. Please go through this link : http://mongoosejs.com/docs/connections.html – Amol M Kulkarni Jan 24 '13 at 11:22
  • 1
    @AmolMKulkarni: I know this is the format the mongoose use to specify connection. But the OP wanted to know how he could use a password that contained an '@'? This a password like "p@ssw0rd" (which is a lame password). The url would be "monbgodb://username:p@ssw0rd@host:port/db" which is mis-interpreted by mongoose (ie. it splits at the first @ instead of the last). – Sylvain Defresne Jan 24 '13 at 12:13
  • @SylvainDefresne: Thanks for update from your end. Its correct The url would be "monbgodb://username:p@ssw0rd@host:port/db" – Amol M Kulkarni Jan 24 '13 at 12:43
  • Got misunderstood by one wrong answer here, which is already downvoted – Amol M Kulkarni Jan 24 '13 at 13:05
  • 2
    The character `@` in your password need to be encoded in the URL. The encoded `@` character is `%40`. However, the `%` character need to be encoded too. So, if your password is, lets say, `p@ss`, the final encoded password should be `p%2540ss` – Michael Pacheco Feb 05 '19 at 00:22
  • { useNewUrlParser: true } did the trick for me – masterxilo May 13 '19 at 21:03
  • @SylvainDefresne how can you change the password in Mongo `Atlas`? – Timo Sep 01 '22 at 18:46
  • @SylvainDefresne It is in "add new database user" in "atlas cloud". – Timo Sep 01 '22 at 18:55

16 Answers16

192

Use this syntax:

// use %40 for @
mongoClient.connect("mongodb://username:p%40ssword@host:port/dbname?authSource=admin", { 
        useNewUrlParser: true
    }, function(err, db) {

    }
);
Lahiru Chandima
  • 22,324
  • 22
  • 103
  • 179
Andrey Hohutkin
  • 2,703
  • 1
  • 16
  • 17
83

If your password has special characters:

const dbUrl = `mongodb://adminUsername:${encodeURIComponent('adminPassword')}@localhost:27017/mydb`;
Jalasem
  • 27,261
  • 3
  • 21
  • 29
vanduc1102
  • 5,769
  • 1
  • 46
  • 43
  • 9
    This is the answer that should get more love as it fixes the complete problem, not just the very specific use case of the OP. – spikyjt Mar 04 '20 at 11:16
  • 1
    This is working great, just for info if someone missed it, you still need to pass {useNewUrlParser: true} as the second argument when connecting using mongoose.connect() – Harnam Singh May 05 '21 at 07:59
  • 1
    This should really be the accepted answer as this takes care of the root cause -- special characters within the pass/username require encoding as the mongo connection string uses the URI spec. RFC2396 – prasanthv Jul 14 '21 at 15:00
31

Use the options parameter of the mongoose.connect call to specify the password instead of including it in the URL string:

mongoose.connect('mongodb://localhost/test',
                 {user: 'username', pass: 'p@ssword'},
                 callback);
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
7

Try this one, my friends:

    mongoose.connect("mongodb://localhost:27017/test?authSource=admin",
                     {user: 'viettd', pass: 'abc@123'});

test is my db name
admin is my the db for authenticating
viettd is my username
abc@123 is my password

Viet Tran
  • 1,173
  • 11
  • 16
6

I have also faced the same issue. I have solved by adding encoded password into connection string. And it works just well.

(1) Encode your password from https://www.url-encode-decode.com
(2) Replace your password with encoded one.
(3) It should work well.

For example:
Actual Password: ABCDEX$KrrpvDzRTy`@drf.';3X
Encoded Password: ABCDEX%24KrrpvDzRTy%60%40drf.%27%3B3X

mongodb://user1:ABCDEX%24KprpvDzRTy%60%40drf.%27%3B3X@dstest.com:1234,ds1234-test.com:19889/mongo-dev?replicaSet=rs-ds123546978&ssl=true',

Nyambaa
  • 38,988
  • 9
  • 29
  • 35
prisan
  • 1,251
  • 12
  • 9
  • 1
    not the best advice, to recommend sending the password to an untrusted source... – Guy Dec 23 '19 at 09:08
  • 1
    As @guyarad said, you shouldn't expose your database password, and is not suitable if you change passwords regularly. And the reason for this comment is that, you don't need other softwares / sites to do that, `encodeURIComponent()` is the built-in function that can do the job. – 27px Nov 01 '20 at 15:28
5

use pwd instead pass, that worked for me for version3.2

mongoose.connect('mongodb://localhost/test',
                 {user: 'username', pwd: 'p@ssword'},
                 callback);
AKASH
  • 416
  • 1
  • 7
  • 19
5

If you use Mongodb native Node.js driver, this is what works for me as of 3.1 driver version. Assume your url doesn't contain auth info.

MongoClient = require('mongodb').MongoClient;
let options = {
    useNewUrlParser: true,
    auth: {
        user: 'your_usr',
        password: 'your_pwd'
    }
};
MongoClient.connect(url, options, callback);

Or if you wanna include auth info in your url, do this:

let url = "mongodb://username:" + encodeURIComponent("p@ssword") + "@localhost:27017/database"
toadead
  • 1,038
  • 16
  • 29
3

None of the solutions mentioned above worked for me. I researched it further and found out that I had to include the useNewUrlParser parameter.

mongoose.connect(db, {
    useNewUrlParser : true
    },
    err => {
    if (err){
        console.error('Error: ' + err)
    }
    else{
        console.log('Connected to MongoDb')
    }
})

From what I understand, you need a specific version of MongoDB in order to use this. For more details, check Avoid “current URL string parser is deprecated” warning by setting useNewUrlParser to true

It is to get rid of the warning but clearly the version also affect the required parameter.

I haven't tested all special characters but it definitely works with '@#$'.

Hope this helps.

Thierry
  • 6,142
  • 13
  • 66
  • 117
1

sometimes you need to connect to the DB using other tools that accept string only as connection string. so just change the @ sign with %40

dang
  • 1,549
  • 1
  • 20
  • 25
  • for example (dont worry dummy user and pass) change this: mongodb://kipkip:Nolalola22@@ds031223.mlab.com:3d223/mishlo to: mongodb://kipkip:Nolalola22%40@ds031223.mlab.com:3d223/mishlo – dang Jan 12 '17 at 08:39
1

Also, if your password contains a percentage, %, Because the percent ("%") character serves as the indicator for percent-encoded octets, it must be percent-encoded as "%25" for that octet to be used as data within a URI

for example, if your password is John%Doe, the new transformed password will be John%25Doe or If password is Paul%20Wait, New Password will be Paul%2520Wait

mongoClient.connect("mongodb://username:John%25Doe@host:port/dbname", function(err, db) {
// password is John%Doe
    }`enter code here`
);
Ryan M
  • 18,333
  • 31
  • 67
  • 74
0

This solution requires an extra dependency, but it was what finally worked for me.

Add mongodb-uri to your project and the following lines to your code:

const mongoose = require('mongoose')
const mongodbUri = require('mongodb-uri')
let mongooseUri = mongodbUri.formatMongoose(config.mongo.uri)
mongoose.connect(mongooseUri, config.mongo.options)

I found this suggestion in mongoose's GitHub issue #6044.

lpacheco
  • 976
  • 1
  • 14
  • 27
0

Use this,

mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true}).then(()=>console.log("DB connected"));
David Buck
  • 3,752
  • 35
  • 31
  • 35
0

If the username or password includes the at sign @, colon :, slash /, or the percent sign % character, use percent encoding.

Mongo Docs: https://docs.mongodb.com/manual/reference/connection-string/

Community
  • 1
  • 1
Matt M
  • 592
  • 1
  • 5
  • 27
0

I was attempting this in python and I had a similar error. This worked for me.

import pymongo

client = pymongo.MongoClient("mongodb://username:12%40password@ip:27017/sample_db") 
db = client.sample_db
# print the number of documents in a collection
print(db.collection.count())

12%40password represents your password and assumes it has a special character (e.g. @ - represented by %40) - username is your mongodb username , ip - your ip address and sample_db the database under mongodb that you wish to connect to.

user8291021
  • 326
  • 2
  • 9
0

This one worked for me

This one is a MongoDB 2020 Update If You're using a separate env file then just add your

mongoose.connect('url',
{
    useNewUrlParser: true, 
    useUnifiedTopology: true 
});
crazyCoder
  • 75
  • 1
  • 13
0

Apparently I faced something similar, but I was not able to find any way around it other than avoiding special characters in password. I tried other special characters (^ % &) none of them works with the password in URL string. But the MongoDB doc says only

: / ? # [ ] @

these characters need to be percent-encoded.

I tried encoding most of them in my password combinations, but none of them are working.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Vishnu Mohan
  • 37
  • 1
  • 5