Node-oracledb's createPool Method without SYSDBA - node.js

I met a obstacle when using node-oracledb's createPool method. Detailed description:
Created a table in Oracle 12c using SYSDBA privilige (Table name: guest)
Input some records into "guest" table.
Confirmed the input records are available with "commit" and "select" command in Windows 7 command
Wrote code as below:
var oracledb = require("oracledb");
(async ()=>{
try{
await oracledb.createPool({
_enableStats: true,
user: '[username]',//my username in database
password: '[password]', //my password in database
connectString: 'localhost/orcl',
poolAlias: "chougou",
});
var connection = await oracledb.getPool('chougou').getConnection();
var result = await connection.execute('select * from guest');
await connection.close();
console.log(result)
}catch(err){
console.log(err.message)
}
})();
The result shows:
ORA-00942 Table or View do not exist
But, if I changed the select sentence to connection.execute('select * from dual'), I could get the normal result.
I analyzed above, and got the conclusion: In oracledb.createPool{()}, it must exist one connection privilige attribution like _enableStats: user: password: connectString: to connect Database with SYSDBA.
As my experience, in PHP, we can use $session_mode in oci_connect() to give a privilige for connecting.
Could anyone help me to find this attribution in oracledb.createPool{()}?
Chen
chougou1982#hotmail.com

Regarding terminology, what you did was create a table as a user who happened to have SYSDBA system privileges. As a guess that user was SYS.
Fundamentally you shouldn't be creating user tables as SYS. Create another user.
You wouldn't want to be creating a whole pool of users in node-oracledb with such a high privilege level as SYSDBA because of the security implications.
You can only use privilege with standalone connections in node-oracledb.
You could grant access to other users to read or update the table. But see the second point above.

Related

Performing search queries in Active Directory with Node.js Application

The web application I'm developing involves accessing the Active Directory in order to perform the necessary authorization and authentication operations. The backend of my application involves nodeJS and it should be using Active Directory NPM package in order to access the Active Directory of my organization. I happen to be totally new to Active Directory and I'm a bit confused with the usage of Active Directory NPM package. I read the usage section of this package and it shows that it (the config object variable) requires the user to input four arguments which are as follows: url, baseDN, username & password. Below is the code in the usage section:
var ActiveDirectory = require('activedirectory');
var config = { url: 'ldap://dc.domain.com',
baseDN: 'dc=domain,dc=com',
username: 'username#domain.com',
password: 'password' }
var ad = new ActiveDirectory(config);
Out of these 4 parameters that are there in the config object, I'm not able to understand the role of the baseDN parameter and how do we have to use it when performing search queries in Active Directory. ( I have highlighted this parameter in the above image. )
It would be really great if someone could explain the usage of this particular parameter and how do we have to use it, when performing search queries in Active Directory.
Also, I was wondering if someone could refer me to a source or a tutorial that offers a clear explanation regarding the performing search queries in Active Directory with Nodejs Application. Any help would be highly appreciated. Thanks!
The concept of the base DN is not specific to just Node.js. It's the same for all LDAP queries, regardless of where you do it from.
DN stands for Distinguished Name, which is an identifier for each object in the directory. The base DN (or sometimes called "search root") defines the scope of your search. In most cases, the baseDN will be the root of your domain, like DC=example,DC=com (if your domain name is example.com). However, you can set it to a specific OU if you only want results from that OU: OU=Users,DC=example,DC=com.
In short: the search will only return results where the DN ends with the baseDN you specified.
For documentation on how performing queries in AD in Node.js, you have to refer to the packages that are created for that purpose, like the activedirectory package you found. However, that package is no longer maintained (hasn't been touched in 4 years). The activedirectory2 was forked from that and is actively maintained. You are better off using that.
We can search user using fineUser method in activeDirectory in the following way after user Authentication
var options = {
url: domaincontroller,
tlsOptions: {
ca: [fs.readFileSync(caCertRoot), fs.readFileSync(caCertIntermediate)],
rejectUnauthorized: true,
},
baseDN: "DC=domain,DC=com",
bindDN: `${req.body.username}#domain.com`,
bindCredentials: `${req.body.password}`,
filter: "(objectClass=*)",
attributes: { user: ["givenName", "c", "co"], group: ["com"] },
};
/* Search Functionality */
const ad = new ActiveDirectory(Object.assign(config, options));
ad.findUser(req.body.username, function (err, user) {
if (err) {
res.writeHeader(401, { "Content-Type": "text/html" });
res.write(
`<h3>Username or Password is not valid, please try again!</h3>`
);
res.send();
return;
} else {
res.send({ msg: "user logged successfully", ...user });
}
});

Error Message: MongoError: bad auth Authentication failed through URI string

I'm trying to connect to my mongoDB server via the connection string given to me by mongo:
"mongodb+srv://david:password#cluster0-re3gq.mongodb.net/test?retryWrites=true"
In my code I am calling the connection through mongoose like this (obviously putting in my password):
const mongoose = require('mongoose');
const db = 'mongodb+srv://david:<password>#cluster0-re3gq.mongodb.net/test?retryWrites=true'
mongoose
.connect(db, {
useNewUrlParser: true,
useCreateIndex: true
})
.then(() => console.log('MongoDB connected...'))
.catch(err => console.log(err));
When I run the code I am getting the following error
"MongoError: bad auth Authentication failed."
Any ideas of what that could mean?
I had the same problem, and in my case, the answer was as simple as removing the angle brackets "<"and ">" around <password>. I had been trying: my_login_id:<my_password>, when it should have been my_login_id:my_password.
I think you're confused with the mongodb account password and user password.
You should use user password, not account password.
That was the reason of my case.
It happens because your provided password in connection string is wrong and most probably you have mistaken cluster password with your login password, in simple words while connecting with Atlas Cluster we can't use our account password by which we login to the Atlas website. In both case we can reset our cluster password and solve this issue.
To Solve The Issue Follow Below Given Steps
Step 1:- Click Database Access From left Side Navigation of MongoDB Atlas page.
Step 2:- Select your username and and click on the edit button from right side.
Step 3:- Click to change password.
Step 4:- Click update user.
While changing password try to keep password only alphabetical because special characters need encoding.
that's all now you can connect.
Don't use creds in the URI, use like this instead:
mongoose.connect(mongodb+srv://clusterAnything.mongodb.net/test?retryWrites=true&w=majority, { user: process.env.MONGO_USER, pass: process.env.MONGO_PASSWORD, useNewUrlParser: true, useUnifiedTopology: true })
In my case left and right characters are there
like this:
<Password>
so changed to:
Password
Checklist to follow:
1) Make sure you're using the correct password (the DB user password and not the Mongo account).
2) When entering your password, make sure all special characters are URL encoded (for example: p#ssword should be p%40ssword).
3) If you don't remember your password of your DB user - go to Database Access (if you're using Mongo Atlas) -> select your DB user -> edit -> create a new password -> don't forget update to click on 'Update User'.
(!) Security warning: Do not write the password in plain text inside your code - Follow the suggestions given here.
Are you writing your password in the place of <password>? If your aren't, a good practice is to create a environment variable on your operating system and call it using process.env.[your variable]. Ex:
const password = process.env.YOURPASSWORDVARIABLE
const db = 'mongodb+srv://david:'+password+'#cluster0-re3gq.mongodb.net/test?retryWrites=true'
Better yet, you can also put your whole url connection string inside a env variable:
Adding to above answers, the issue seemed to revolve around a wrong Database password input for me, because of a distortion of what i read as my current password from the Atlas menu and what MongoDB Atlas really saved as my current password.
There seems to be a "bug" when using the "Copy" button when choosing a new password.
What helped me was the following:
Open Atlas in the web
Go to "Database Access"
Click "Edit" on the Database user
Choose "Password" for authentication method
Click "Edit Password"
Click "Show" in the password field
Click "Autogenerate Secure Password"
DO NOT press "Copy" button to copy, but use manual selection via mouse and copy the text via right-click of your mouse or keyboard command
Click "Update User" below
Then:
Go through the list of Database users to make sure that no other Database user has the same password you just newly generated.
Now try your Username/Password combination again using this connection string (leaving out the placeholder characters '$' and '[]':
'mongodb+srv://$[username]:$[password]#$[hostlist]/$[database]?retryWrites=true'
I noticed that when I autogenerated a new password by clicking and then clicking the "Copy" button, that the autogenerated password was reset to the old password. Therefore I assumed the new autogenerated password is correct, but in reality it was my old password, which in addition was the same as for another Database user. I could not comprehend that until I clicked "Show" on the password input field.
Not only the password
Check all the fields it could be the password the user or the database. If you misspelt any of these you will have an authentication error.
Go to the database access on the left pane under security:
And in case change the password using edit button. Let's say your password is: P#sW0rd
You can compile the URL using the information contained in the Database Users screen:
client = MongoClient("mongodb+srv://giac:P#sW0rd#cluster0.wjdtk.mongodb.net/testc?retryWrites=true&w=majority")
The other answers did not say that even if you mispell the database name you have a authentication error.
This worked for me
mongoose.connect(
`mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PASS}#cluster0.adv0t.mongodb.net/${process.env.MONGO_DATABASE}?retryWrites=true&w=majority`,
{
useNewUrlParser: true,
useUnifiedTopology: true,
}
);
Create a ".env" file (you need to install dotenv before this ) in the parent directory(if you choose a custom location, add the following in server.js / app.js).
require('dotenv').config({ path: '/custom/path/to/.env' }) //uses custom location
Otherwise, add this in the server.js / app.js (the one that initiates server).
require('dotenv').config() //uses default location
In the ".env" file, define the user, password and database like this
MONGO_USER=uSerName
MONGO_PASS=p#sSW0rd
MONGO_DATABASE=myDatabase
I faced a similar issue, weirdly enough it got resolved when I created a new user in database access. This time though I clicked on autogenerate password. It should not matter but in my case it solved the issue.
I forgot to update the user after generating and copying the password and was wondering why it wasn't working. I saw the update button later. I was not visible to me earlier. lol. Solved the problem.
Database Access => edit user => generate/copy password => update it!
It worked for me.
remember to make sure you have updated it.
Just remove the angle brackets from both sides of your password.
Wrong Answer :
const db = 'mongodb+srv://username:<password>#cluster0-re3gq.mongodb.net/test?retryWrites=true'
Correct Answer :
const db = 'mongodb+srv://username:password#cluster0-re3gq.mongodb.net/test?retryWrites=true'
Finally, it worked for me to used that connection string with a lower grade that NodeJs versions(2.2.12 or later) cluster url. And After that make sure you have to whitelist your current IP Address from Atlas MongoDB. It should display like 0.0.0.0/0 (includes your current IP address) in Network Access section in Atlas MongoDB.
Connect to cluster NodeJs version 2.2.12 or later
And the main issue was where I am storing that connection string url in a constant that part. So initially,I was storing that connection string value in single/double quote but every time I was getting Authentication failure error as it was unable to parse that "Password" value from Atlas mongoDB . So I used backtick (``)instead of single/double quote to store that connection string.
Sample code where I am connecting mongoDB Atlas through a NodeJs application.
const DB_USER = 'your username in atlas mongodb';
const PASSWORD = encodeURIComponent('your password in atlas mongodb');
const url = `mongodb://${DB_USER}:${PASSWORD}#cluster0-shard-00-00.3ytbz.mongodb.net:27017,cluster0-shard-00-01.3ytbz.mongodb.net:27017,cluster0-shard-00-02.3ytbz.mongodb.net:27017/sample-db?ssl=true&replicaSet=atlas-z26ao5-shard-0&authSource=admin&retryWrites=true&w=majority`;
mongoose.connect(url,
{
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: true
})
.then(() => {
console.log('Connected to database !!');
})
.catch((err)=>{
console.log('Connection failed !!'+ err.message);
});
I just had this problem knowing that I was using the correct username, password and DBname.
I tried to change the password for the db user to double check, but it still didn't work.
I then instead created a new user, gave the user admin role, set the password etc, and then used that new user and password (same dbname) for the connection and it worked.
I don't know exactly what the issue was, but hoping it can help some of you save some time :)
After spending almost an hour messing with the URI, changing permissions and configurations and whatnot, I found out I was getting this error message because of a VPN connection I had active. After shutting down the VPN I was able to connect.
So if nothing else works for you, there might be something in your system preventing a connection to be successfully established and mongodb is just responding with bad auth
I had this same challenge but I discovered that making my IP address set to my current IP prevented me from accessing the services. Making the database accessible from anywhere was appropriate to access the database either using mongo shell or mongo compass.
The same problem i faced with mongoDB password authentication failed.
"Error: bad auth Authentication failed."
As per Pawan's suggestion given above i replaced my login password in MONGO_URI link with database password and it works. be sure to check that one also.
If you not generated the generate new one or if created earlier then replace with new one.
In my case, my password was wrong, to diagnostic the error, I have been follow the next steps:
I have to try connection by command line:
Whit this command: mongo "mongodb+srv://cluster0-j8ods.mongodb.net/test" --username :
The response was again: 2020-04-26T11:48:27.641-0500 E QUERY [js] Error: bad auth Authentication failed. :
then I'm change the password for my user, in my case, root user. and thats it, I'm authorized
mongodb+srv://jehat123:<password>#jehatarmancdeniz-x2yf7.mongodb.net/question-answer?retryWrites=true&w=majority
Delete all of password part
Use like this:
mongodb+srv://jehat123:yourpass#jehatarmancdeniz-x2yf7.mongodb.net/question-answer?retryWrites=true&w=majority
You can also get rid of this error by creating a new database user by going to Database Access from the left side and then go to Add New Database User from right right.
Now create a new username and password, click OK. Now replace this new username and password into the MongoUri.
In My case the above error got resolved by setting password variable directly.
DATABASE = "test"
#PASSWORD = os.environ.get("YOUR_PASSWORD") #This line was causing an error in code
PASSWORD = "YOUR_PASSWORD" # I added directly password variable
client = connect(
DATABASE,
host=f"mongodb+srv://mano:{PASSWORD}#cluster0.e2arj.mongodb.net/?retryWrites=true&w=majority",
alias="default",
)
Changing password worked for me
nB: Not the atlas password
mongodb+srv://david:password#cluster0-re3gq.mongodb.net/test?retryWrites=true
Replace 'password' with the password you registered for the username specified.
Replace 'test' after net with the name of the db you created in collections.
For me it turned out to be, that I had to tab out of the password field on the MongoDB Atlas page. Before clicking "Update User"
Just go to the "MongoDB Users tab" where you will find the user list. Click on edit where you can reset the password. Sometimes resetting the password can resolve the issue.
if you having this issue and learning mongo by official mongo trainings use m001-mongodb-basics as password for your db. And the correct db name is Sandbox (if you followed all steps)
This happened to me recently, I found out if you have updated your Mongo Db Password recently, your older databases will still be using the old password.
You can get around this by adding a new user to your Mongo db account or just use the old password.
Go to Database on the left hand side
click on browse collection
click on Add My Own Data
provide database name and collection name
Again click on database
click on connect ,connect your application
Select node.js
copy the connection string and keep it in your server.js
9)click on database access , edit password, autogenerate password
Copy the password with mouse , click update user
replace in the url string with this password and you are done
First, check your password(regenerate)
if not solved.
please check your MongoDB connect URL
this piece of code is unique,
mongodb+srv://reduxJobBox:<password>#cluster0.b08r8ak.mongodb.net/?retryWrites=true&w=majority

Getting the user id from a Firestore Trigger in Cloud Functions for Firebase?

In the example bellow, is there a way to get the user id (uid) of the user who wrote to 'offers/{offerId}'? I tried to do as described here but it doesn't work in Firestore.
exports.onNewOffer = functions.firestore
.document('offers/{offerId}')
.onCreate(event => {
...
});
I was struggling on this for a while and finally contacted the firebase Support:
The event.auth.uid is undefined in the event object for firestore database triggers. (It works for the realtime Database Triggers)
When I console.log(event) I can’t find any auth in the output.
The official support answer:
Sorry the auth is not yet added in the Firestore SDK. We have it listed in the next features.
Keep an eye out on our release notes for any further updates.
I hope this saves someone a few hours.
UPDATE:
The issue has been closed and the feature will never be implemeted:
Hi there again everyone - another update. It has been decided that unfortunately native support for context.auth for Firestore triggers will not be implemented due to technical constraints. However, there is a different solution in the works that hopefully will satisfy your use case, but I cannot share details. On this forum we generally keep open only issues that can be solved inside the functions SDK itself - I've kept this one open since it seemed important and I wanted to provide some updates on the internal bugs tracking this work. Now that a decision has been reached, I'm going to close this out. Thanks again for everyone's patience and I'm sorry I don't have better news. Please use the workaround referenced in here.
Summary of how I solved this / a workable solution:
On client
Add logged in/current user's uid (e.g. as creatorId) to entity they're creating. Access this uid by storing the firebase.auth().onAuthStateChanged() User object in your app state.
In Firebase Firestore/Database
Add a Security Rule to create to validate that the client-supplied creatorId value is the same as the authenticated user's uid; Now you know the client isn't spoofing the creatorId and can trust this value elsewhere.
e.g.
match /entity/{entityId} {
allow create: if madeBySelf();
}
function madeBySelf() {
return request.auth.uid == request.resource.data.creatorId;
}
In Firebase Functions
Add an onCreate trigger to your created entity type to use the client-supplied, and now validated, creatorId to look up the creating user's profile info, and associate/append this info to the new entity doc.
This can be accomplished by:
Creating a users collection and individual user documents when new accounts are created, and populating the new user doc with app-useful fields (e.g. displayName). This is required because the fields exposed by the Firebase Authentication system are insufficient for consumer app uses (e.g., displayName and avatarURL are not exposed) so you can't just rely on looking up the creating user's info that way.
e.g. (using ES6)
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
const APP = admin.initializeApp()
export const createUserRecord = functions.auth.user()
.onCreate(async (userRecord, context) => {
const userDoc = {
id: userRecord.uid,
displayName: userRecord.displayName || "No Name",
avatarURL: userRecord.photoURL || '',
}
return APP.firestore().collection('users').doc(userRecord.uid).set(userDoc)
})
Now that you have a validated creatorId value, and useful user objects, add an onCreate trigger to your entity type (or all your created entities) to look up the creating user's info and append it to the created object.
export const addCreatorToDatabaseEntry = functions.firestore
.document('<your entity type here>/{entityId}')
.onCreate(async (snapshot, context) => {
const userDoc = await APP.firestore().collection('users').doc(snapshot.data().creatorId).get()
return snapshot.ref.set({ creator: userDoc.data() }, { merge: true })
})
This clearly leads to a lot of duplicated user info data throughout your system -- and there's a bit of clean up you can do ('creatorId` is duplicated on the created entity in the above implementation) -- but now it's super easy to show who created what throughout your app, and appears to be 'the Firebase way'.
Hope this helps. I've found Firebase to be super amazing in some ways, and make some normally easy things (like this) harder than they 'should' be; on balance though am a major fan.
The documentation states clearly that the context.auth param is only available in the Realtime Database.
This field is only populated for Realtime Database triggers and
Callable functions. For an unauthenticated user, this field is null.
For Firebase admin users and event types that do not provide user
information, this field does not exist.
Personally I realized that I had the userId already in the path of my data.
export const onCreate = functions.firestore.document('docs/{userId}/docs/{docId}')
.onCreate((snapshot, context) => {
const userId = context.params.userId;
Until this is added to firestore functions a workaround is to add the user_id as a field when creating a document then deleting after. You can then grab it in the function onCreate then after you use it for what you need it for, while still in the function, just delete the field from that document.
As already suggested above, the workaround will be to add a user_id field with the data itself and then read it on the server.
The drawback with this approach will be a security loophole. As we are not verifying the user id on the server, any other user will be able to impersonate other users by sending their id with the data.
For security critical applications, the solution for this will be to use security rules to verify that the correct user_id has been sent with the data
allow write: if resource.data.user_id == request.auth.uid;
You could add your data via Callable function, from which you can access current user id:
exports.addNewOffer = functions.https.onCall(async (data, context) => {
const uid = context.auth.uid
const writeResult = await admin.firestore().collection('offers').add({ ... })
...
return { id: writeResult.id, ... }
})
What is about snap._fieldsProto.uid.stringValue
Example:
exports.hello = functions.firestore.document('hello/{worldId}').onCreate((snap, context) => {
console.log(snap._fieldsProto.uid.stringValue)
});
This should do the trick:
exports.newMessage = functions.firestore
.document('groups/messages/{messageId}')
.onCreate((snap, context) => {
var fromId = snap.data().fromId;
You can get the current signed-in user tokenId by calling getIdToken() on the User: https://firebase.google.com/docs/reference/functions/functions.auth.UserInfo

pg-promise one connection per user

Dear community and vitaly-t hopefully,
I am building a website / server with pg-promise.
I use postgre role/group login for authentification.
I don't know if I am doing the things correctly but I would like that each user use their own postgres connection to query the database.
So in practice, I create a connection for each user when they connect (if it is not already existing).
To do so, I have created a Pool object with an ugly 'fake promise' and a pgUser object:
var pgPool = function(pg){
var _this=this;
var fakePromise = function(err){
var _this=this;
_this.err=err
_this.then=function(cb){if(!err){cb();return _this}else{return _this};};
_this.catch=function(cb){if(err){cb(_this.err)}else{return _this};};
return _this;
};
_this.check= function(user){
if (_this[user]){
return _this[user].check();
}else{
return new fakePromise({error:'Echec de connection à la base de
données'})
}
}
_this.add = function(user,password){
var c={};
c.host = 'localhost';
c.port = 5432;
c.database = 'pfe';
c.poolSize = 10;
c.poolIdleTimeout = 30000;
c.user=user;
c.password=password
if (!_this[user]){
_this[user] = new pgUser(c,pg);
return _this[user].check();
}else{
_this[user].config.password=password;
return _this[user].check();
};
};
return _this;
};
var pgUser = function(c,pg){
var _this=this
_this.config = c
_this.db = new pg(_this.config)
_this.check = function(){
return _this.db.connect();
};
return _this;
};
And here is how I add a user to the 'pool' during the login POST handling
pool.add(req.body.user,req.body.password).then(function(obj){
obj.done();
req.session.user = req.body.user;
req.session.password = req.body.password;
res.redirect("/");
return;
}).catch(function(err){
options.error='incorect password/login';
res.render('login', options);
return;
});
I am sure it could irritate pro developpers and you would be kind if you could explain me the best way :
is that a good idea to have one connection to the database per user
(it seems legit to have a good security)?
how can I use the pg-promise library better to avoid this ugly custom 'pool' object?
Sincerly thank you.
I have contacted the security responsible of my project, doing research as associate profressor in security (CITI lab)...here is his comment :
====================
Since it is my fault, I will try to explain ;-). First, to be clear, I
work on the security side (notably access control and RDBMS security)
but am not very familiar with JS or promises.
Our aim is to implement the principle of least privilege with a defense
in depth approach. In this particular case, this means that a query sent
by an unprivileged user should not have admin rights on the database
side. RDBMS such as PostgreSQL provide very powerful, expressive and
well-tested access control mechanisms : RBAC, row-level security,
parametrized views, etc. These controls, indeed, are usually totally
ignored in web applications which use the paradigm "1 application == 1
user", this user has thus admin role. But heavy clients often use
several different users on the database side (either one per final user
or one per specific role) and thus benefit from the access control of
the database.
Access control from the DB is an addition to access control in the web
application. AC in the webapp will be more precise but may probably
suffer from some bugs ; AC in the DB will be a bit more laxist but
better enforced, limiting damages in case of an application bug.
So in our case, we want to create a DB user for every application user.
Then, the connection to the database belongs to this specific user and
the database can thus enforce that a simple user cannot execute admin
operations. An intermediate possibility would be to drop some privileges
before executing a query, but our preferred way is to connect to the
database as the currently logged-in user. The login-password is sent by
the user when he authenticates and we just pass it to the DBMS.
Scalability is not (yet) an issue for our application, we can sacrifice
some scalability for this type of security.
Would you have any hints to help us achieve this ?
==================

Authentication always failing when connecting to MongoDB

I am using node/express
node_modules =
"mongodb": "2.0.33",
"mongoose": "3.8.15",
mongo shell version: 3.0, and mongo 3.0
I'm able to connect to my mongoDB just fine, but if I pass in any authentication parameters, it will fail:
connection error: { [MongoError: auth failed] name: 'MongoError', ok: 0, errmsg: 'auth failed', code: 18 }
The following shows up in the logs when this happens:
2015-06-13T15:10:09.863-0400 I ACCESS [conn8] authenticate db: mydatabase { authenticate: 1, user: "user", nonce: "xxx", key: "xxx" } 2015-06-13T15:10:09.863-0400 I ACCESS [conn8] Failed to authenticate user#mydatabase with mechanism MONGODB-CR: AuthenticationFailed UserNotFound Could not find user user#mydatabase
I've done quite a few patterns to try to get this to work.
Here's what happens when I do the show users command in the mongo shell while on the appropriate database:
{
"_id" : "mydatabase.user",
"user" : "user",
"db" : "mydatabase",
"roles" : [
{
"role" : "readWrite",
"db" : "mydatabase"
}
]
}
Here's my attempt to connect to this particular database while passing in the correct parameters:
mongoose.connect('mongodb://user:password#host:port/mydatabase');
For good measure I also tried passing in an options hash instead of passing the params via uri:
mongoose.connect('mongodb://host:port/mydatabase',{user: 'user',pass: 'password'});
Strangely enough, this works when done from the shell:
mongo mydatabase -u user -p password
so clearly, the credentials are right, and it's lining them up to the correct database, but something about the connection with Mongoose is not working...
Here is the shell command I passed in when creating that user:
db.createUser({
user: "user",
pwd: "password",
roles: [
{ role: "readWrite", db: "mydatabase" }
]
});
I got a success message with this, and I confirmed by calling the show users command when using the mydatabase set
I'm at a real loss here.... Here's some of the prior research I have done that hasn't yet given me success:
Cannot authenticate into mongo, "auth fails"
This answer suggests that it wouldn't be working because authentication happens at a database level, so I'm missing some sort of config option for my mongo instance, however the docs now say that such level authentication is disabled by default, and the docs the answer links to are since deprecated.
MongoDB & Mongoose accessing one database while authenticating against another (NodeJS, Mongoose)
uses older version of Mongo that still have addUser
On top of that, I don't see why that would work given it suggests I add a parameter to the 'auth' options that isn't listed in the documentation:
http://mongodb.github.io/node-mongodb-native/api-generated/db.html#authenticate
http://mongoosejs.com/docs/connections.html
Basically what I'm trying now, but isn't working.
authenticate user with mongoose + express.js
I've tried a number of answers that involved doing something of this sort, that gave me the same error. Also, I'd rather avoid these type of solutions that require +80 lines of code to authenticate for now. I just want to get basic authentication down first.
You mentioned that you are using MongoDB 3.0. In MongoDB 3.0, it now supports multiple authentication mechanisms.
MongoDB Challenge and Response (SCRAM-SHA-1) - default in 3.0
MongoDB Challenge and Response (MONGODB-CR) - previous default (< 3.0)
If you started with a new 3.0 database with new users created, they would have been created using SCRAM-SHA-1.
So you will need a driver capable of that authentication:
http://docs.mongodb.org/manual/release-notes/3.0-scram/#considerations-scram-sha-1-drivers
If you had a database upgraded from 2.x with existing user data, they would still be using MONGODB-CR, and the user authentication database would have to be upgraded:
http://docs.mongodb.org/manual/release-notes/3.0-scram/#upgrade-mongodb-cr-to-scram
Specific to your particular environment Mongoose compatibility for that version doesn't appear to support 3.0 due to the MongoDB Node.js driver that is in use (see the compatibility page on the Mongoose site--sorry, can't post more than 2 links currently).
I would suggest you update Mongoose.
Mongo v3.0+:
The db field (outside of the role object) matters here. That is not settable bby passing it into the createUser command afaict.
The way to set it is to type 'use ' before issuing the creatUser command.
Unless you do it that way, the db object inside role may have he correct and intended value, but the auth will still not work.

Resources