问题
I don't think I described the problem properly through the title. However, I have a .NET Core Web Api application which all of my tenants will use. As well as the single API instance I have a single frontend Vuejs instance which all tenants can use as a 'portal'.
These tenants each have their own database. Currently the api's all require a header of tenant
within a request to specify which tenant the request is being made for, this will then create a db connection according to the tenant from the request.
You can't pretend your a different tenant as all of the api's require authorization against a tenants db.
I guess the thing I'm stuck on is determining the tenant a user belongs to when logging in using the single frontend vuejs instance. It's not a problem when it comes to just using the api's as the tenant can be sent via the header of the request, but im not sure how to resolve the tenant in order to determine the correct db to use by a sign in which will be used across all tenants.
Apologies if I didn't explain the problem well, it's a tricky situation.
回答1:
where are your users live? You might have to extract users info into a separate identity database that contains info which user belongs to which tenant. That can be as simple as Key-Value store: email->TenantId. So for login you'll have to look up this tenantId
, then authenticate against user info in the correct tenant database.
Or you can pull all your user information into a single database that contains all the info about the user, including password hash. You can also use some identity provider like Auth0 or IdentityServer - these have ability to add user properties like TenantId
.
Whatever the scenario you choose, you'll have to have a single place where you map user to a tenant. Looking through multiple databases for user info is not ideal.
If your Vue.js app is using your backend API you can set TenantId in cookie or other way to persist this info between calls.
回答2:
If all the DB's have the same structure I would use only one database and use the tenant id as index, that way you have only one connection in your project and the problem is solved. Otherwise you will have to check all databases every time a user tries to login.
回答3:
I would use a similar solution like this
https://docs.servicestack.net/multitenancy
ServiceStack provides a number of ways of changing the database connection used at runtime based on an incoming Request. You can use a Request Filter, use the [ConnectionInfo] Request Filter Attribute, use the [NamedConnection] attribute on Auto Query Services, access named connections in Custom Service implementations or override GetDbConnection(IRequest) in your AppHost.
Whether you use WebAPI or ServiceStack is upto you (I, personally, am a fan of the latter). Basically, what you have to do is create an interface IForTenant and have your service-models implement them.
public interface IForTenant
{
string TenantId { get; }
}
You'll need a DB Connection Factory that takes tenant id as an argument to return an IDbConnection instance. Then you create a request filter, that checks if a request is of type IForTenant and get the correct IDbConnection instance from the aforementioned factory.
来源:https://stackoverflow.com/questions/56909845/creating-single-application-with-multi-dbs