使用多个数据库创建单个应用程序
Creating single application with multi dbs
我认为我没有通过标题正确描述问题。但是,我有一个 .NET Core Web Api 应用程序,我的所有租户都将使用它。除了单个 API 实例外,我还有一个前端 Vuejs 实例,所有租户都可以将其用作 'portal'.
这些租户各有自己的数据库。目前 api 都需要 header of tenant
在请求中指定请求是针对哪个租户,然后这将根据来自租户的租户创建数据库连接请求。
您不能假装您是不同的租户,因为所有 api 都需要针对租户数据库的授权。
我想我遇到的问题是在使用单个前端 vuejs 实例登录时确定用户所属的租户。仅使用 api 不是问题,因为可以通过请求的 header 发送租户,但我不确定如何解析租户以确定正确的登录后使用的数据库将在所有租户中使用。
抱歉,如果我没有很好地解释问题,这是一个棘手的情况。
如果所有数据库都具有相同的结构,我将只使用一个数据库并使用租户 ID 作为索引,这样您的项目中只有一个连接,问题就解决了。否则,每次用户尝试登录时,您都必须检查所有数据库。
您的用户住在哪里?您可能必须将用户信息提取到一个单独的身份数据库中,该数据库包含哪个用户属于哪个租户的信息。这可以像 Key-Value store: email->TenantId 一样简单。因此,对于登录,您必须查找此 tenantId
,然后根据正确租户数据库中的用户信息进行身份验证。
或者您可以将所有用户信息提取到一个数据库中,该数据库包含有关用户的所有信息,包括密码哈希。您还可以使用一些身份提供者,如 Auth0 或 IdentityServer - 它们能够添加用户属性,如 TenantId
.
无论您选择哪种方案,您都必须有一个地方将用户映射到租户。通过多个数据库查找用户信息并不理想。
如果您的 Vue.js 应用正在使用您的后端 API,您可以在 cookie 中设置 TenantId 或以其他方式在调用之间保留此信息。
我会使用类似这样的解决方案
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.
使用 WebAPI 还是 ServiceStack 由您决定(我个人是后者的粉丝)。基本上,您要做的是创建一个接口 IForTenant 并让您的 service-models 实现它们。
public interface IForTenant
{
string TenantId { get; }
}
您需要一个数据库连接工厂,它将租户 ID 作为 return IDbConnection 实例的参数。然后创建一个请求过滤器,检查请求是否属于 IForTenant 类型,并从上述工厂获取正确的 IDbConnection 实例。
我认为我没有通过标题正确描述问题。但是,我有一个 .NET Core Web Api 应用程序,我的所有租户都将使用它。除了单个 API 实例外,我还有一个前端 Vuejs 实例,所有租户都可以将其用作 'portal'.
这些租户各有自己的数据库。目前 api 都需要 header of tenant
在请求中指定请求是针对哪个租户,然后这将根据来自租户的租户创建数据库连接请求。
您不能假装您是不同的租户,因为所有 api 都需要针对租户数据库的授权。
我想我遇到的问题是在使用单个前端 vuejs 实例登录时确定用户所属的租户。仅使用 api 不是问题,因为可以通过请求的 header 发送租户,但我不确定如何解析租户以确定正确的登录后使用的数据库将在所有租户中使用。
抱歉,如果我没有很好地解释问题,这是一个棘手的情况。
如果所有数据库都具有相同的结构,我将只使用一个数据库并使用租户 ID 作为索引,这样您的项目中只有一个连接,问题就解决了。否则,每次用户尝试登录时,您都必须检查所有数据库。
您的用户住在哪里?您可能必须将用户信息提取到一个单独的身份数据库中,该数据库包含哪个用户属于哪个租户的信息。这可以像 Key-Value store: email->TenantId 一样简单。因此,对于登录,您必须查找此 tenantId
,然后根据正确租户数据库中的用户信息进行身份验证。
或者您可以将所有用户信息提取到一个数据库中,该数据库包含有关用户的所有信息,包括密码哈希。您还可以使用一些身份提供者,如 Auth0 或 IdentityServer - 它们能够添加用户属性,如 TenantId
.
无论您选择哪种方案,您都必须有一个地方将用户映射到租户。通过多个数据库查找用户信息并不理想。
如果您的 Vue.js 应用正在使用您的后端 API,您可以在 cookie 中设置 TenantId 或以其他方式在调用之间保留此信息。
我会使用类似这样的解决方案
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.
使用 WebAPI 还是 ServiceStack 由您决定(我个人是后者的粉丝)。基本上,您要做的是创建一个接口 IForTenant 并让您的 service-models 实现它们。
public interface IForTenant
{
string TenantId { get; }
}
您需要一个数据库连接工厂,它将租户 ID 作为 return IDbConnection 实例的参数。然后创建一个请求过滤器,检查请求是否属于 IForTenant 类型,并从上述工厂获取正确的 IDbConnection 实例。