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

Multi tool use
Multi tool use












0















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);









share|improve this question























  • 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
















0















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);









share|improve this question























  • 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














0












0








0


0






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);









share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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



















  • 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












1 Answer
1






active

oldest

votes


















0














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.






share|improve this answer























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    0














    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.






    share|improve this answer




























      0














      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.






      share|improve this answer


























        0












        0








        0







        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.






        share|improve this answer













        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 4 at 20:09









        ANorseDudeANorseDude

        217




        217






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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
            poi7sk9OoWU Y6 RLeWEiX16U4A r5IW81ZDdtjuGvcyDcZwYKS5ylVlNSy,cvkBd6 1NEku,lo snu774GhYcWg5W

            Popular posts from this blog

            Monofisismo

            Angular Downloading a file using contenturl with Basic Authentication

            Olmecas