So I have a vapor \ fluent app that works fine with local mongo instance, here's current mongo.json:
{
"database" : "vapor",
"port" : "27017",
"host" : "127.0.0.1",
"user" : "",
"password" : ""
}
I've deployed a free MongoDB Atlas 3 replica set and I wonder how do I connect the app to it?
Fluent's MongoDB integration is using an outdated version of MongoKitten. Currently we're at MongoKitten 4. MongoKitten 1, which is being used in Fluent currently supports just a fraction of the features with a much worse performance.
Check that your mongod instance is listening on the necessary network interfaces
Check that your firewall is open and you can connect to the mongod process from your application node
Check that your mongod is secure, i.e. you can connect only with known credentials
In the application's mongo.json:
"host": "replica_set_name/first_RS_node_address, second_RS_node_address, third_RS_node_address",
"user": "your_user_name",
"password": "wery_secret"
Related
I am using AWS document db v4.0.0. It works fine with my application using MongoDB driver to connect. But when I try to use mongo shell it gives me some errors on basic query:
db.myCollection.find({})
Error: error: {
"ok" : 0,
"code" : 303,
"errmsg" : "Feature not supported: 'causal consistency'",
"operationTime" : Timestamp(1645150705, 1)
}
Does this mean DocumentDB is not compatible with mongo shell?
Your code is missing the actual connection part, but make sure you have the TLS keys placed on the machine.
Your connection string should be something like this:
mongo --ssl host docdb-2020-02-08-14-15-11. cluster.region.docdb.amazonaws.com:27107 --sslCAFile rds-combined-ca-bundle.pem --username demoUser --password
There is actually a really good example/explanation in the official AWS Documentation
Casual consistency isn't supported in DocumentDB. From your mongo shell you can run "db.getMongo().setCausalConsistency(false)" then re-run your find operation.
https://docs.mongodb.com/manual/reference/method/Mongo.setCausalConsistency/
I have 3 databases in my MongoDB server. I am using pymongo to do some scripting with Python3.
I want to use the latest versions and practices. Once I open the client and pick the database, the API for pymongo.MongoClient.['mydatabase'].authenticate is deprecated.
https://api.mongodb.com/python/current/api/pymongo/database.html
Authentication prior to picking the database (while dialing the client) doesn't seem to flow down toward the database. Not just for pymongo, but also when I use mongo shell. So I have a feeling this is the issue.
script.py
import pymongo
from pymongo import MongoClient
u = getUser() # function which prompts for username
p = getPassword() # getpass.getpass('Password')
uri = formatUri(u, p) # formats 'mongodb://%s:%s#%s'.format(user, password, host)
client = MongoClient(uri)
db = client['mydb']
col = db.mycollection
for doc in col.find():
print(doc)
I get the error that I am not authorized for the database. I know my account works in shell but I have to dial the client first then use the db and then auth.
Here's a mongo shell example:
$ mongo
MongoDB shell version: v3.4.10
Connecting to: mongodb://127.0.0.1:port
MongoDB server version: v3.4.10
> use mydb
switched to mydb
> db.auth("user", "pass")
1
Any idea how I can either auth after picking the database or once I use the db it remembers the context I dialed with?
You seem to be missing some concepts here so I'll basically answer as a "guide" to what you should be doing instead. So "authentication' is not really something you do "after" connection, but rather you need to be "looking in the right place" when you actually attempt to authenticate.
We can start this by essentially following the process outlined in Enable Auth from the core documentation, but specifically altered because you want to be running this "test" under your own user account and local directory.
Revision Steps - Straight from Documentation
So first would would want to pick a local working directory and make a path for the database storage files underneath that. On *nix based systems you can do something like:
mkdir -p scratch/data/db
cd scratch
Then we want to startup a separate MongoDB instance without any other options. Making sure the port does not conflict with any other running instance:
mongod --port 37017 --dbpath data/db
In a new terminal or command line window, you can then connect to the shell:
mongo --port 37017
You always want at least one account with administrative privileges to at least "create accounts" and alter them in case you get in trouble, so create one:
use admin
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
}
)
Now exit the shell and close the existing mongod instance running in the other terminal or command prompt and then start it again using --auth:
mongod --auth --port 37017 --dbpath data/db
Specific User - Make sure you follow these
Now you actually want to create a user that will be "used by your application". So these steps are important to ensure you get it right.
Log into a shell using your "adminstrative user":
mongo -u admin -p admin --port 37017 --authenticationDatabase 'admin'
You can alternately do the db.auth() method as shown in the question, but as noted this must be authorised on the "admin" namespace.
The next thing you want to do is create a user with access to "mydb" as a namespace with the readWrite role. For kicks, we are also going to let this user have the readAnyDatabase allowing them to "list" all databases namespaces, if not actually being able to do anything else with them.
IMPORTANT: You create ALL your users in the "admin" namespace. And this will be very important in future releases:
use admin
db.createUser(
{
"user": "myuser",
"pwd": "password",
"roles": [
{ "role": "readWrite", "db": "mydb" },
"readAnyDatabase"
]
}
)
Just for additional output, let's look at the current created users:
db.getUsers()
[
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
},
{
"_id" : "admin.myuser",
"user" : "myuser",
"db" : "admin",
"roles" : [
{
"role" : "readWrite",
"db" : "mydb"
},
{
"role" : "readAnyDatabase",
"db" : "admin"
}
]
}
]
See how these have expanded in naming, and particularly the values assigned to the various "db" keys on each user. This should give you a little more insight into how MongoDB looks this up and why.
Python Connection
Finally we just want to connect from python. So presuming you have python and pymongo installed already, then it's just a simple listing to verify:
import pymongo
from pymongo import MongoClient
client = MongoClient('mongodb://myuser:password#localhost:37017');
db = client['mydb']
col = db.test
col.remove()
col.insert_one({ "a": 1 })
for doc in col.find():
print(doc)
Which shows the document created and listed without problem:
{u'a': 1, u'_id': ObjectId('5a08e5e0760108251722a737')}
Note that we don't actually need to make any mention of "admin" here, because this is the default where the driver "expects the accounts to be" and where you really "should" be doing it.
But I did it the wrong way
So let's say you originally got all confused and created the user under "mydb" instead:
use mydb
db.createUser({ "user": "bert", "pwd": "password", "roles": ["readWrite"] })
If you go look in "admin" that user is not there. But if you look on "mydb":
use mydb
db.getUsers()
[
{
"_id" : "mydb.bert",
"user" : "bert",
"db" : "mydb",
"roles" : [
{
"role" : "readWrite",
"db" : "mydb"
}
]
}
]
So you can see where the actual user data is now kept and how it has been recorded.
The simple case here is you "must" tell MongoDB where to obtain the authentication from for this user:
client = MongoClient('mongodb://bert:password#localhost:37017/mydb');
See how we add "mydb" on to the connection string. This is how it's done.
This is actually "in progress" to be made consistent with ALL drivers in how connections are made and where authentication happens as well as where you select the database. But there are basic rules:
If no other database namespace is provided with connection details for authentication credentials, then "admin" is taken to be the default.
Where there is a database namespace provided on the connection string, this will be used for authentication and this is the actual intent of the database namespace on the connection string.
Though other drivers "presently" differ in the role of the database namespace on the connection string, the usage is being changed to be consistent with all drivers that "using" a database namespace is in fact an API call, rather than being assigned from the connection string.
So where you need to authenticate depends on "where you created the user". But you should really be noting that "admin" is the place where you "should" be doing this instead of anywhere else.
Deprecation of Authenticate after connect
Whilst all drivers actually do have a similar method to authenticate(), which is used much like the shell example in the question, this method is now considered DEPRECATED as is mentioned throughout the content of the answer it is "intended" that you actually store your users in the "admin" namespace:
"Changed in version 3.5: Deprecated. Authenticating multiple users conflicts with support for logical sessions in MongoDB 3.6. To authenticate as multiple users, create multiple instances of MongoClient."
This is why the whole answer here is based on NOT using that method as you are meant to creating new connection instances, or using the "sessions" functionality available from MongoDB 3.6 instead.
I have 3 databases in my MongoDB server. I am using pymongo to do some scripting with Python3.
I want to use the latest versions and practices. Once I open the client and pick the database, the API for pymongo.MongoClient.['mydatabase'].authenticate is deprecated.
https://api.mongodb.com/python/current/api/pymongo/database.html
Authentication prior to picking the database (while dialing the client) doesn't seem to flow down toward the database. Not just for pymongo, but also when I use mongo shell. So I have a feeling this is the issue.
script.py
import pymongo
from pymongo import MongoClient
u = getUser() # function which prompts for username
p = getPassword() # getpass.getpass('Password')
uri = formatUri(u, p) # formats 'mongodb://%s:%s#%s'.format(user, password, host)
client = MongoClient(uri)
db = client['mydb']
col = db.mycollection
for doc in col.find():
print(doc)
I get the error that I am not authorized for the database. I know my account works in shell but I have to dial the client first then use the db and then auth.
Here's a mongo shell example:
$ mongo
MongoDB shell version: v3.4.10
Connecting to: mongodb://127.0.0.1:port
MongoDB server version: v3.4.10
> use mydb
switched to mydb
> db.auth("user", "pass")
1
Any idea how I can either auth after picking the database or once I use the db it remembers the context I dialed with?
You seem to be missing some concepts here so I'll basically answer as a "guide" to what you should be doing instead. So "authentication' is not really something you do "after" connection, but rather you need to be "looking in the right place" when you actually attempt to authenticate.
We can start this by essentially following the process outlined in Enable Auth from the core documentation, but specifically altered because you want to be running this "test" under your own user account and local directory.
Revision Steps - Straight from Documentation
So first would would want to pick a local working directory and make a path for the database storage files underneath that. On *nix based systems you can do something like:
mkdir -p scratch/data/db
cd scratch
Then we want to startup a separate MongoDB instance without any other options. Making sure the port does not conflict with any other running instance:
mongod --port 37017 --dbpath data/db
In a new terminal or command line window, you can then connect to the shell:
mongo --port 37017
You always want at least one account with administrative privileges to at least "create accounts" and alter them in case you get in trouble, so create one:
use admin
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
}
)
Now exit the shell and close the existing mongod instance running in the other terminal or command prompt and then start it again using --auth:
mongod --auth --port 37017 --dbpath data/db
Specific User - Make sure you follow these
Now you actually want to create a user that will be "used by your application". So these steps are important to ensure you get it right.
Log into a shell using your "adminstrative user":
mongo -u admin -p admin --port 37017 --authenticationDatabase 'admin'
You can alternately do the db.auth() method as shown in the question, but as noted this must be authorised on the "admin" namespace.
The next thing you want to do is create a user with access to "mydb" as a namespace with the readWrite role. For kicks, we are also going to let this user have the readAnyDatabase allowing them to "list" all databases namespaces, if not actually being able to do anything else with them.
IMPORTANT: You create ALL your users in the "admin" namespace. And this will be very important in future releases:
use admin
db.createUser(
{
"user": "myuser",
"pwd": "password",
"roles": [
{ "role": "readWrite", "db": "mydb" },
"readAnyDatabase"
]
}
)
Just for additional output, let's look at the current created users:
db.getUsers()
[
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
},
{
"_id" : "admin.myuser",
"user" : "myuser",
"db" : "admin",
"roles" : [
{
"role" : "readWrite",
"db" : "mydb"
},
{
"role" : "readAnyDatabase",
"db" : "admin"
}
]
}
]
See how these have expanded in naming, and particularly the values assigned to the various "db" keys on each user. This should give you a little more insight into how MongoDB looks this up and why.
Python Connection
Finally we just want to connect from python. So presuming you have python and pymongo installed already, then it's just a simple listing to verify:
import pymongo
from pymongo import MongoClient
client = MongoClient('mongodb://myuser:password#localhost:37017');
db = client['mydb']
col = db.test
col.remove()
col.insert_one({ "a": 1 })
for doc in col.find():
print(doc)
Which shows the document created and listed without problem:
{u'a': 1, u'_id': ObjectId('5a08e5e0760108251722a737')}
Note that we don't actually need to make any mention of "admin" here, because this is the default where the driver "expects the accounts to be" and where you really "should" be doing it.
But I did it the wrong way
So let's say you originally got all confused and created the user under "mydb" instead:
use mydb
db.createUser({ "user": "bert", "pwd": "password", "roles": ["readWrite"] })
If you go look in "admin" that user is not there. But if you look on "mydb":
use mydb
db.getUsers()
[
{
"_id" : "mydb.bert",
"user" : "bert",
"db" : "mydb",
"roles" : [
{
"role" : "readWrite",
"db" : "mydb"
}
]
}
]
So you can see where the actual user data is now kept and how it has been recorded.
The simple case here is you "must" tell MongoDB where to obtain the authentication from for this user:
client = MongoClient('mongodb://bert:password#localhost:37017/mydb');
See how we add "mydb" on to the connection string. This is how it's done.
This is actually "in progress" to be made consistent with ALL drivers in how connections are made and where authentication happens as well as where you select the database. But there are basic rules:
If no other database namespace is provided with connection details for authentication credentials, then "admin" is taken to be the default.
Where there is a database namespace provided on the connection string, this will be used for authentication and this is the actual intent of the database namespace on the connection string.
Though other drivers "presently" differ in the role of the database namespace on the connection string, the usage is being changed to be consistent with all drivers that "using" a database namespace is in fact an API call, rather than being assigned from the connection string.
So where you need to authenticate depends on "where you created the user". But you should really be noting that "admin" is the place where you "should" be doing this instead of anywhere else.
Deprecation of Authenticate after connect
Whilst all drivers actually do have a similar method to authenticate(), which is used much like the shell example in the question, this method is now considered DEPRECATED as is mentioned throughout the content of the answer it is "intended" that you actually store your users in the "admin" namespace:
"Changed in version 3.5: Deprecated. Authenticating multiple users conflicts with support for logical sessions in MongoDB 3.6. To authenticate as multiple users, create multiple instances of MongoClient."
This is why the whole answer here is based on NOT using that method as you are meant to creating new connection instances, or using the "sessions" functionality available from MongoDB 3.6 instead.
I recently opened up a free mLab account, and I'm trying to access the number of open connections in my database through the shell.
I never had problems with the command line when I was running mongodb locally, but now nothing works.
To connect I do this:
mongo ds127044.mlab.com:27044/db_name -u db_user -p db_password
And it show I'm successfully connected.
After that I run:
db.serverStatus()
And get:
{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { serverStatus: 1.0 }",
"code" : 13,
"codeName" : "Unauthorized"
}
But according to my console I'm listed as the owner of the db:
{
"_id": "db_name.db_user",
"user": "db_user",
"db": "db_name",
"roles": [
{
"role": "dbOwner",
"db": "db_name"
}
]
}
Is there something I'm doing wrong in the command line or is it something particular to my account with mLab?
Seems to be something related with your user's roles.
All documentation here: https://docs.mongodb.com/manual/reference/built-in-roles/#cluster-admin-roles/ (specifically cluesterMonitor information)
Say:
...The admin database includes the following roles for administering the
whole system rather than just a single database...
And in this Doc https://docs.mongodb.com/manual/core/security-built-in-roles/
Say:
Every database includes: Database Administration Roles... The
admin database includes the following roles for administering the
whole system: Cluster Administration Roles
'serverStatus' is realted to clusterMonitor role so..
Try to change it:
roles: [ { role: "clusterMonitor", db: "admin" },
{ role: "dbOwner", db: "db_name" }]
Good luck!
Not a mongodb expert, but here's what I found in the docs.
db.serverStatus() shares instance info in its output. For example:
host
The system’s hostname. In Unix/Linux systems, this should be the same as the output of the hostname command.
mLab wouldn't expose host info to end users, who should only have access to the dbs they're creating--specifically, the db you logged into.
Similarly, you'll run into issues with other calls like show dbs, since that would expose all the dbs (including dbs for other users!) existing alongside your own.
I imagine that the only commands that will work are ones that expose info completely related to only your db. I suggest hitting up a more export mongodb admin perhaps in a separate question for that definitive list, if necessary.
I fixed this exact issue by changing my mac settings to allow remote login.
System Preferences -> Sharing -> Remote Login: On
I have the following user:
{
"_id" : "admin.root",
"user" : "root",
"db" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
And for my database:
{
"_id" : "mydb.mydbDbOwner",
"user" : "mydbDbOwner",
"db" : "mydb",
"roles" : [
{
"role" : "dbOwner",
"db" : "mydb"
}
]
}
I can't connect via Robomongo on localhost:
The same goes for...
Database: mydb
User Name: root
Database: mydb
User Name: mydbDbOwner
How can I fix this problem?
Robomongo 0.8.x doesn't have support for the new SCRAM-SHA-1 authentication which was the default authentication method added in MongoDB 3.0.
Robomongo 0.9.0 RC4 (Feb 2016) added support for SCRAM-SHA-1, but if you are using a modern version of MongoDB server you should upgrade to the latest version of Robomongo (now Robo3T) currently available.
There is also an officially maintained free GUI, MongoDB Compass, which is more actively updated than Robo3T. MongoDB Compass 1.22+ (Sept 2020) includes an embedded MongoDB shell.
I was experiencing exactly the same issue on Mac. I removed the Robomongo client and download the latest version from their website. It just works :)
You can change localhost to 127.0.0.1
You can try Mongo-Express (a web-based tool).
However, you need to upgrade the MongoDB-Node.js library to be at least (1.4.29) according to Upgrade to SCRAM.
I tried and it worked for my case. You can find the below useful command for that:
npm install mongo-express
cd node-modules/mongo-express
Change the config.default.js file to config.js and update it to include your database connection (e.g., username, password, connection's URL, etc.)
Edit the package.jon file and change the version of MongoDB to "~1.4.29"
Run: npm update
To start the web application: execute command "node app" and the web site will be available at http://localhost:8081/.
I just upgraded to the new version 1.0 of Robomongo. As a few people stated in here, 0.8.x didn’t support SCRAM-SHA-1, which is default in MongoDB 3.0. In prior versions it was MONGODB-CR.
But anyone who is downloading Robomongo from this point on shouldn't have an issue with authentication.
https://robomongo.org/
This bottom links explains SCRAM-SHA a bit more. I suggest reading into it if heavily using MongoDB.
SCRAM
Possibility for connection through an SSH tunnel with Robomongo is back in the RC8 version. See GitHub issue Where is the SSH tunnel settings on v 0.9.0 RC2 Mac version #1008.