Managing Multi Tenant DB Connections - php

I know this subject has been discussed among many in SO but I have a specific issue that I would like to get your opinions on.
I apologize in advance since this is exactly not a coding issue.
I am a self learnt developer and I do not have CS degree exposure or any sort. Majority of everything I know is learnt through the web.
I am planning on developing a multi tenant app which uses angular for front end, laravel for backend/api connecting and mysql to store data.
I plan on assigning a unique key for each tenant identified by 2 or 3 letters (to be decided later) which the user will have to type upon login to identify the tenant. Let's call it the tenantId.
Also, I am contemplating of using a subdomain and getting the subdomain as the tenant id for seperation. Lets assume for this scenario that I have the tenantId with me.
Also, laravel will have 2 connections defined. Lets say tenantconnection(to hold individual tenant db credentials) and masterconnection.
Masterconnection holds db credentials for a database that holds the tenantkey, db username, db password, db name, mysql server address in one of it's tables.
Upon getting the db credentials from mastertenant, laravel will update the tenantconnection initialised in the database.php file in the config folder.
So every API call, laravel will have to connect to master get credentials for tenantconnection and then call the db.
In your opinion/experience how practical/applicable is this?
Can this pose any latency even if the db server and app server is within the same datacenter?
Is this method of connecting an accepted method of connecting in a multi tenant environment?
Also, on every API call to laravel i plan on sending the tenantid through JWT. I am not really comfortable of saving tenantid on localstorage.
Can localstorage be manipulate by using any tools such as firebug or something similar of that nature?
I thought of using sharing the db and using schemas in the same db,but the app is designed to hold financial data so I thought that separating them would be the best. I have researched the pros and cons and decided that using a seperate db for each tenant is the best.
Your feedback is greatly appreciated.
Sorry if posted on the wrong stack site.
Sorry about the long read time.

Most of your questions are opinion-based, which makes it kind of off-topic. I would just add a comment, but it wouldn't fit.
Can this pose any latency even if the db server and app server is within the same datacenter?
I don't think a 10~20ms delay will impose any problems. Make sure you understand the basic of MySQL indexes because if someday you face database problems it is important to not automatically assume it's the tenancy fault. It's usually bad indexes.
Is this method of connecting an accepted method of connecting in a multi tenant environment?
I think so, I'm using it like this. The only difference is that my application is not Web App + API. I use blade.
Also, on every API call to laravel i plan on sending the tenantid through JWT. I am not really comfortable of saving tenantid on localstorage.
I don't know your project specs. If each user can have access to more than 1 tenant, then yes, this seem to be a good approach. If each user BelongsTo a
unique tenant, then why bother with tenant-id at all? Just take the tenant from the user authenticated by the token.
Can localstorage be manipulate by using any tools such as firebug or something similar of that nature?
How to view or edit localStorage

Related

Why api is used when you can fetch data directly from database using sql query?

I am a newbie to the web application. I just understood what is an api and why it is used by reading some online blog. But I was wondering why to use an api to fetch data(or insert data) when you can directly fetch data from database using PHP and mysql.(I am sorry if this question sounds stupid.) An answer with example would be great. Thanks
API are used to make communications more secure. With an API you can add encryption, different users and roles and a lot more. With MySQL you can not do that on the same level.
Future more, MySQL is a service, and if you work directly with it, it has to be open on a Port. Here you can not add not as well protection as you can on a Webserver.
An API can also add some logic. Maybe you want to control the input given by a request to it. Or maybe you want to have some additional calculations going on, before you make any INSERT or UPDATE to the database. This can help you to have your database clean.
If the System where the database and the API is located at, decides to change the database from lets say MySQL to PostgreSQL or anything else, every service connecting to it will have to change its code to make it work with the new environment.
So, an API can be more secure and has some standard everyone can rely on, even if the APIs background changes.

SaaS ways to access multiple databases and user authentication mechanisms with master database

I'm in the process of building a saas application with a master database for all transactions and the user base and seperate databases for each tenant. Each tenant is given an unique sub domain and based on that, the correct database is pointed to the tenant. The web application is built using php and MySQL is used for data storage.
I have couple of problems and to begin with;
When a user visits the tenants home page (E.g. Sub.abc.com), there will be a login functionality available. Since the username password and the user base is in the master database, how would I authenticate a user? Is it through a seperate database connection for the master database or via web apis? What is the best way?
There will be roles created by a tenant. So assume the staff for a specific tenant is retrieved by calling a web api and the role is stored in the tenant database along with the user id. Is this the right way forward because there is no direct foreign key mapping and also once the users are retrieved should I store in the tenant database or just hold it in memory?
In case the business owner wants a report about something specific for each tenant database, what would be the best way to grab all the data from each and every individual tenant database?
How can we capture each tenants database usage, file storage and show in the super admin?
how would I authenticate a user? Is it through a seperate database connection for the master database or via web apis? What is the best way?
Be careful with the "best way" questions - this would point this question towards being off topic as opinion based.
If your application is completely closed source (which I imagine it is), then it doesn't matter. You can access your master database directly if you want to, because all of your client implementations will be part of your overall software package.
That being said, for scalability and maintainabilty it's probably a better idea to build an authentication API interface and use that, so you don't need to manage the database connection component of your client software.
...the role is stored in the tenant database along with the user id. Is this the right way forward because there is no direct foreign key mapping and also once the users are retrieved should I store in the tenant database or just hold it in memory?
This is fine. The users are common to all of your implementations, but the roles are unique to each client implementation. This indicates that the way you're approaching it is correct in that you authenticate first, then assign the client's role to the user once logged in. You should check this against your local database (obviously), then assign it to the user's session so it sticks around for the duration of their visit.
In case the business owner wants a report about something specific for each tenant database, what would be the best way to grab all the data from each and every individual tenant database?
This is too broad to answer. You should also be careful here, because the client's data may not be yours to report on!
How can we capture each tenants database usage, file storage and show in the super admin?
Again, quite broad, but I assume that you could achieve something like this by querying the MySQL server for database statistics on each client database and do the same for the file storage by querying the server that hosts the client's files.
I hope this is helpful, please narrow down your questions a little more if you'd like more specific help.
Be careful with the "best way" questions - this would point this
question towards being off topic as opinion based.
If your application is completely closed source (which I imagine it
is), then it doesn't matter. You can access your master database
directly if you want to, because all of your client implementations
will be part of your overall software package.
That being said, for scalability and maintainabilty it's probably a
better idea to build an authentication API interface and use that, so
you don't need to manage the database connection component of your
client software.
Agreed. See the thing is for these kind of scenarios it is very difficult to find answers especially on multi-tenancy.
What do you mean by closed source?
If i can have authentication APIs to retrieve data from the master database, how would i host it in a way only the access is granted within the application and outside parties cannot access it? Later on we need to have services exposed to outside users as well. In this case is it better to expose this from now on or work on separate services later? What are the best neat PHP web service libraries do you know other than NuSOAP?
This is fine. The users are common to all of your implementations, but
the roles are unique to each client implementation. This indicates
that the way you're approaching it is correct in that you authenticate
first, then assign the client's role to the user once logged in. You
should check this against your local database (obviously), then assign
it to the user's session so it sticks around for the duration of their
visit.
That is correct! The users are common to all implementations and this is stored in the master database and not on individual tenant databases.By roles i meant, per tenant application, the tenant can create roles which are within the tenant application such as the billing unit, accounts, front desk, etc. So these user_id and role_id is stored in the tenant's database. That's why i asked since the user_id is not directly mapped to the master database's user table if it's okay.
This is too broad to answer. You should also be careful here, because
the client's data may not be yours to report on!
For now let's assume the super admin wants to know roles of every tenant.In this case how would i retrieve the data from all tenant databases? Do we use Views for this or since we are using mysql how can i achieve this?
Again, quite broad, but I assume that you could achieve something like
this by querying the MySQL server for database statistics on each
client database and do the same for the file storage by querying the
server that hosts the client's files.
Extremely sorry about this. We basically want to track the usage of tenant databases to see if they exceed the amount we agreed on. That's why. I hope there is a way to achieve this.
Also, for the site images, is it better to store on the hard disk or in the database as BLOBs? End of the day we need to think about Scalability as well as a way images will load with less bandwidth consumption?

connecting two laravel website with one database

I have made a website for Employers in Laravel 5. Now I want to connect and sync it with a second website on different domain but same server. The 2nd website is for jobseekers which will listen to events for database change by 1st application. For example if a candidate is shortlisted by a employer that corresponding event should be captured and handled in jobseeker application. Please suggest a way to do that, I am not much experienced in Laravel.
You can have the first website make an API call to the second to let it know something has changed. Alternatively, you can have the first website use Laravel's event system in conjunction with the Queue system. Your second application can connect to the database of first application to retrieve and modify its queue.
The API solution provides a bit more flexibility, especially if they were to ever be on separate servers. I would choose whichever you are more comfortable with, it wouldn't take long to implement either if you change your mind later.

Secure MySQL Connection on Client Side Apps?

I'm currently building out an application that stores user data in a database. Part of the specifications of the application dictates that the user should be able to access their data from anywhere, this includes phone based apps that I'm planning to write with HTML5 and port using one of the various HTML to app converters.
My issue here, is that since the data needs to be access from several devices, I'll need some sort of central database to store the information. I have no problem writing code to query the database, but the issue of how to handle it on the phone side is giving me a little trouble.
I've read before that it's unwise to embedded the database login credentials in each app, and this makes sense. However, then I'm not sure how I would need to go about adding the ability to connect to the databases.
I'm thinking about adding in some sort of database connection layer to my application. I'm thinking of having some sort of key added to the app itself, which is required by the database to connect. That way, the login credentials are only stored in one place, and on my server.
There are still some concerns with this approach in my mind.
Is this going to be a large performance issue; having to connect first to a script before querying the database and then having it perform some sort of check to send the data back to the user?
Is this really necessary and any more secure? How bad of an idea is to to directly code the database login into the app itself, and how much risk of any potential problems does this actually migrate?
When it comes down to it, I don't have much experience with this type of application, and I'm wondering if my idea is good enough to work, or if there is any other ways that are clearly better that I should look into.

Combination of Node.JS(+ Socket.io) and PHP, what about users and changing Socket ID's

I have been playing around with Node.js for two days now, I am slowly understanding how it works. I have checked multiple threads and posts now but I seem to either misunderstanding them or the way I am thinking about this application is completely wrong.
My application is mainly based on PHP and uses Node.js as a notifications system.
I first wanted to this solely in Node.js but I am more familiar with PHP so that is why I only want to use Node.js as a notifications system.
I do not have any real code to show as I have been mainly playing around and see all what Node can do and so far it seems to be the thing I need, there is one thing I just can't figure out or seem to mis understand. So far I figured out how to send data between the user and the server and used socket.io for this.
So, what if I have a user, which is registered and logs-in on my application. He then has a socket id from socket.io, but when the user leaves my application and comes back the next day his socket ID is changed because it seems to change on every connection. I need to have my users somehow always have the same socket ID or something else which tells my node.js server that it should only send data to one specific user or multiple users. Also, as the socketid seems to change on every request it is even changed when the user visits a different page so I don't ever seem to know which user is what.
I am a little confused and the flow of working with both PHP and Node.js is still a little mystery to me so I hope my question is clear. I dont want to be depending on many modules as I find all these different modules kind of confusing for a beginner like me.
As long as PHP-Node.js are using sessions stored somewhere else other than flag file sessions let's say a cache service or a database mysql or nosql ..
you can use the "same flat file" sessions thought cache or database could be make your application "more"of course there are additional practises of allowing authenticated users to try to connect by controlling when to render the javascript code that holds the information to connect to socket.io server, where an additional list is stored in memory of all connected having information like username/log/timestamps/session variables/etc..

Categories