One mongoDB-instance, many DBs - how to connect a user to “their” DB without affecting other users?

Multi tool use
I'm building an application (MVC) that will use 4 collections in a DB. When I add new clients to the application they will get their separate DB. So if I have 10 customers, there will be 10 DBs and 40 collections (1 db -> 4 collections)
This way each customer data is seperated from other customers, which is crucial here.
So far I've built the app and everything is working nicely, 'cept one thing.
If Company A logs in and start using the app everything works fine. But when Company A is logged in, and Company B logs in, both Company A AND B will be directed towards Company B:s DB.
I've looked trough my code and I guess this is my own fault because I use .connect (mongoose). When a company logs in the route will fire of a controller that will open a new connection (which overrides the old one) which will redirect all open connections towards that specific DB.
controller.dBlogin.js
mongoose.connect(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
The id is fetched from req.params.id (example: http://webapp.com/login/:id).
As far as I've figured .connect only allows one connection at a given time so I need something that will, simply, allow many connections. So I'm thinking that I could use .createConnection for this,
- https://mongoosejs.com/docs/connections.html#multiple_connections
But i just cant get it to work.
I changed controller.dBlogin.js to
mongoose.createConnection(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
but that only leads to a timeout when the company logs in. How do I use the .createConnections? How do you go from .connect to .createConnection?
Heres the examples of routes, controller, and a model (user-schema).
routes.js
// connect to db, check auth
app.post('/login/:id', dbController.connectDB, dbController.login)
controller.dbLogin.js
exports.**connectDB** = (req, res, next) => {
const id = req.params.id;
// Get Mongoose to use the global promise library
mongoose.Promise = global.Promise;
// Options Conncetion mongodb
const options = {
useNewUrlParser: true,
};
// Connecting to the database
mongoose.connect(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
};
exports.login = (req, res, next) => {
passport.authenticate('local-login', {
successRedirect: '/start', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
})(req, res, next);
};
Example of a model user.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
const Company = require('../models/company.js');
// define the schema for our user model
const userSchema = mongoose.Schema({
local : {
name : {
type: String,
required : true
},
email : {
type : String,
unique : true,
required : true
},
password : String,
active : Boolean,
company : {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company'
}
}
});
// generating a hash for password
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
node.js mongodb express mongoose
add a comment |
I'm building an application (MVC) that will use 4 collections in a DB. When I add new clients to the application they will get their separate DB. So if I have 10 customers, there will be 10 DBs and 40 collections (1 db -> 4 collections)
This way each customer data is seperated from other customers, which is crucial here.
So far I've built the app and everything is working nicely, 'cept one thing.
If Company A logs in and start using the app everything works fine. But when Company A is logged in, and Company B logs in, both Company A AND B will be directed towards Company B:s DB.
I've looked trough my code and I guess this is my own fault because I use .connect (mongoose). When a company logs in the route will fire of a controller that will open a new connection (which overrides the old one) which will redirect all open connections towards that specific DB.
controller.dBlogin.js
mongoose.connect(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
The id is fetched from req.params.id (example: http://webapp.com/login/:id).
As far as I've figured .connect only allows one connection at a given time so I need something that will, simply, allow many connections. So I'm thinking that I could use .createConnection for this,
- https://mongoosejs.com/docs/connections.html#multiple_connections
But i just cant get it to work.
I changed controller.dBlogin.js to
mongoose.createConnection(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
but that only leads to a timeout when the company logs in. How do I use the .createConnections? How do you go from .connect to .createConnection?
Heres the examples of routes, controller, and a model (user-schema).
routes.js
// connect to db, check auth
app.post('/login/:id', dbController.connectDB, dbController.login)
controller.dbLogin.js
exports.**connectDB** = (req, res, next) => {
const id = req.params.id;
// Get Mongoose to use the global promise library
mongoose.Promise = global.Promise;
// Options Conncetion mongodb
const options = {
useNewUrlParser: true,
};
// Connecting to the database
mongoose.connect(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
};
exports.login = (req, res, next) => {
passport.authenticate('local-login', {
successRedirect: '/start', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
})(req, res, next);
};
Example of a model user.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
const Company = require('../models/company.js');
// define the schema for our user model
const userSchema = mongoose.Schema({
local : {
name : {
type: String,
required : true
},
email : {
type : String,
unique : true,
required : true
},
password : String,
active : Boolean,
company : {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company'
}
}
});
// generating a hash for password
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
node.js mongodb express mongoose
What is the standard practise when it comes to building an app that will be used by many different companies and you do not want to keep all the data in the same DB?
– ANorseDude
Jan 1 at 22:03
add a comment |
I'm building an application (MVC) that will use 4 collections in a DB. When I add new clients to the application they will get their separate DB. So if I have 10 customers, there will be 10 DBs and 40 collections (1 db -> 4 collections)
This way each customer data is seperated from other customers, which is crucial here.
So far I've built the app and everything is working nicely, 'cept one thing.
If Company A logs in and start using the app everything works fine. But when Company A is logged in, and Company B logs in, both Company A AND B will be directed towards Company B:s DB.
I've looked trough my code and I guess this is my own fault because I use .connect (mongoose). When a company logs in the route will fire of a controller that will open a new connection (which overrides the old one) which will redirect all open connections towards that specific DB.
controller.dBlogin.js
mongoose.connect(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
The id is fetched from req.params.id (example: http://webapp.com/login/:id).
As far as I've figured .connect only allows one connection at a given time so I need something that will, simply, allow many connections. So I'm thinking that I could use .createConnection for this,
- https://mongoosejs.com/docs/connections.html#multiple_connections
But i just cant get it to work.
I changed controller.dBlogin.js to
mongoose.createConnection(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
but that only leads to a timeout when the company logs in. How do I use the .createConnections? How do you go from .connect to .createConnection?
Heres the examples of routes, controller, and a model (user-schema).
routes.js
// connect to db, check auth
app.post('/login/:id', dbController.connectDB, dbController.login)
controller.dbLogin.js
exports.**connectDB** = (req, res, next) => {
const id = req.params.id;
// Get Mongoose to use the global promise library
mongoose.Promise = global.Promise;
// Options Conncetion mongodb
const options = {
useNewUrlParser: true,
};
// Connecting to the database
mongoose.connect(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
};
exports.login = (req, res, next) => {
passport.authenticate('local-login', {
successRedirect: '/start', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
})(req, res, next);
};
Example of a model user.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
const Company = require('../models/company.js');
// define the schema for our user model
const userSchema = mongoose.Schema({
local : {
name : {
type: String,
required : true
},
email : {
type : String,
unique : true,
required : true
},
password : String,
active : Boolean,
company : {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company'
}
}
});
// generating a hash for password
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
node.js mongodb express mongoose
I'm building an application (MVC) that will use 4 collections in a DB. When I add new clients to the application they will get their separate DB. So if I have 10 customers, there will be 10 DBs and 40 collections (1 db -> 4 collections)
This way each customer data is seperated from other customers, which is crucial here.
So far I've built the app and everything is working nicely, 'cept one thing.
If Company A logs in and start using the app everything works fine. But when Company A is logged in, and Company B logs in, both Company A AND B will be directed towards Company B:s DB.
I've looked trough my code and I guess this is my own fault because I use .connect (mongoose). When a company logs in the route will fire of a controller that will open a new connection (which overrides the old one) which will redirect all open connections towards that specific DB.
controller.dBlogin.js
mongoose.connect(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
The id is fetched from req.params.id (example: http://webapp.com/login/:id).
As far as I've figured .connect only allows one connection at a given time so I need something that will, simply, allow many connections. So I'm thinking that I could use .createConnection for this,
- https://mongoosejs.com/docs/connections.html#multiple_connections
But i just cant get it to work.
I changed controller.dBlogin.js to
mongoose.createConnection(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
but that only leads to a timeout when the company logs in. How do I use the .createConnections? How do you go from .connect to .createConnection?
Heres the examples of routes, controller, and a model (user-schema).
routes.js
// connect to db, check auth
app.post('/login/:id', dbController.connectDB, dbController.login)
controller.dbLogin.js
exports.**connectDB** = (req, res, next) => {
const id = req.params.id;
// Get Mongoose to use the global promise library
mongoose.Promise = global.Promise;
// Options Conncetion mongodb
const options = {
useNewUrlParser: true,
};
// Connecting to the database
mongoose.connect(dbConfig.url + id, options)
.then(() => {
console.log("Successfully connected to the database");
next();
}).catch(err => {
console.log('Could not connect to the database. Exiting now...');
process.exit();
});
};
exports.login = (req, res, next) => {
passport.authenticate('local-login', {
successRedirect: '/start', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
})(req, res, next);
};
Example of a model user.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
const Company = require('../models/company.js');
// define the schema for our user model
const userSchema = mongoose.Schema({
local : {
name : {
type: String,
required : true
},
email : {
type : String,
unique : true,
required : true
},
password : String,
active : Boolean,
company : {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company'
}
}
});
// generating a hash for password
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
node.js mongodb express mongoose
node.js mongodb express mongoose
asked Dec 29 '18 at 22:15
ANorseDudeANorseDude
217
217
What is the standard practise when it comes to building an app that will be used by many different companies and you do not want to keep all the data in the same DB?
– ANorseDude
Jan 1 at 22:03
add a comment |
What is the standard practise when it comes to building an app that will be used by many different companies and you do not want to keep all the data in the same DB?
– ANorseDude
Jan 1 at 22:03
What is the standard practise when it comes to building an app that will be used by many different companies and you do not want to keep all the data in the same DB?
– ANorseDude
Jan 1 at 22:03
What is the standard practise when it comes to building an app that will be used by many different companies and you do not want to keep all the data in the same DB?
– ANorseDude
Jan 1 at 22:03
add a comment |
1 Answer
1
active
oldest
votes
So, for the ones who finds themselves in the same spot:
After reviewing my app and the data it will keep I came to the conclusion that there is no need for splitting multi-tenancy. I reworked the app so when the user fetch or write data they only touch "their" data, and this is controlled backend.
But, I did make a post on mongoose github and got an answer,
See post here: https://github.com/Automattic/mongoose/issues/7386
The author gave a great length which seems to have an actually quite nice implementation of this with express and mongoose: http://nmajor.com/posts/multi-tenancy-with-expressmongoose
I hope this is of any help for you, and if you manage to find a solution or something, where you can show some simple code, please post it as there seems to be a lot of people asking about this.
Cheers.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53973744%2fone-mongodb-instance-many-dbs-how-to-connect-a-user-to-their-db-without-aff%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
So, for the ones who finds themselves in the same spot:
After reviewing my app and the data it will keep I came to the conclusion that there is no need for splitting multi-tenancy. I reworked the app so when the user fetch or write data they only touch "their" data, and this is controlled backend.
But, I did make a post on mongoose github and got an answer,
See post here: https://github.com/Automattic/mongoose/issues/7386
The author gave a great length which seems to have an actually quite nice implementation of this with express and mongoose: http://nmajor.com/posts/multi-tenancy-with-expressmongoose
I hope this is of any help for you, and if you manage to find a solution or something, where you can show some simple code, please post it as there seems to be a lot of people asking about this.
Cheers.
add a comment |
So, for the ones who finds themselves in the same spot:
After reviewing my app and the data it will keep I came to the conclusion that there is no need for splitting multi-tenancy. I reworked the app so when the user fetch or write data they only touch "their" data, and this is controlled backend.
But, I did make a post on mongoose github and got an answer,
See post here: https://github.com/Automattic/mongoose/issues/7386
The author gave a great length which seems to have an actually quite nice implementation of this with express and mongoose: http://nmajor.com/posts/multi-tenancy-with-expressmongoose
I hope this is of any help for you, and if you manage to find a solution or something, where you can show some simple code, please post it as there seems to be a lot of people asking about this.
Cheers.
add a comment |
So, for the ones who finds themselves in the same spot:
After reviewing my app and the data it will keep I came to the conclusion that there is no need for splitting multi-tenancy. I reworked the app so when the user fetch or write data they only touch "their" data, and this is controlled backend.
But, I did make a post on mongoose github and got an answer,
See post here: https://github.com/Automattic/mongoose/issues/7386
The author gave a great length which seems to have an actually quite nice implementation of this with express and mongoose: http://nmajor.com/posts/multi-tenancy-with-expressmongoose
I hope this is of any help for you, and if you manage to find a solution or something, where you can show some simple code, please post it as there seems to be a lot of people asking about this.
Cheers.
So, for the ones who finds themselves in the same spot:
After reviewing my app and the data it will keep I came to the conclusion that there is no need for splitting multi-tenancy. I reworked the app so when the user fetch or write data they only touch "their" data, and this is controlled backend.
But, I did make a post on mongoose github and got an answer,
See post here: https://github.com/Automattic/mongoose/issues/7386
The author gave a great length which seems to have an actually quite nice implementation of this with express and mongoose: http://nmajor.com/posts/multi-tenancy-with-expressmongoose
I hope this is of any help for you, and if you manage to find a solution or something, where you can show some simple code, please post it as there seems to be a lot of people asking about this.
Cheers.
answered Jan 4 at 20:09
ANorseDudeANorseDude
217
217
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53973744%2fone-mongodb-instance-many-dbs-how-to-connect-a-user-to-their-db-without-aff%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Sj 8O0,uyGpQiX7cTq0VPWYQ KWRPQskbCNTkKFf D7s0yeM,TaD,apXnolZ 02 Kwex 989r06Sd KLO9zH N kc6,KIlaCaFTbX
What is the standard practise when it comes to building an app that will be used by many different companies and you do not want to keep all the data in the same DB?
– ANorseDude
Jan 1 at 22:03