Я не думаю, что правильно описал проблему через заголовок. Однако у меня есть приложение .NET Core Web Api, которое будут использовать все мои клиенты. Помимо одного экземпляра API у меня есть один внешний экземпляр Vuejs, который все арендаторы могут использовать в качестве «портала».
Каждый из этих арендаторов имеет свою собственную базу данных. В настоящее время всем API требуется заголовок tenant в запросе, чтобы указать, для какого арендатора делается запрос, после чего будет создано соединение с базой данных в соответствии с арендатором из запроса.
Вы не можете притворяться, что вы другой арендатор, так как все API требуют авторизации в отношении базы данных арендаторов.
Я предполагаю, что то, на чем я застрял, - это определение арендатора, к которому принадлежит пользователь, при входе в систему с использованием единственного экземпляра внешнего интерфейса vuejs. Это не проблема, когда дело доходит до использования API, поскольку арендатор может быть отправлен через заголовок запроса, но я не уверен, как разрешить арендатора, чтобы определить правильную БД для использования по знаку, в котором будет используется всеми арендаторами.
Извините, если я не объяснил проблему хорошо, это сложная ситуация.
@JohnWu Правда, арендатор может быть уникальным идентификатором. Однако, исходя из вашего второго предложения о хранении всех пользователей в общей базе данных, как это будет работать, если пользователь из общей базы данных должен использоваться для фактической базы данных арендатора.
Самый простой способ — объединить всю информацию об арендаторах в этой общей базе данных. Вот что значит мультиарендность. Если им необходимо иметь отдельные базы данных, вам потребуется двойная регистрация с копией списка пользователей каждого арендатора в его базе данных, специфичной для арендатора, что-то вроде того, как «логины» SQL Server сопоставляются с одним или несколькими «пользователями» базы данных.
Являются ли общие базы данных арендаторами хорошей идеей? @ДжонВу
Да! Сама идея мультитенантности заключается в объединении данных. Если вы беспокоитесь о производительности, вы масштабируете, например. добавьте больше процессоров и памяти или больше узлов в свой кластер БД. Это намного дешевле, чем поддержка индивидуальных баз данных для каждого нового клиента, и вам будет намного проще расти вместе с вашим бизнесом.





Если бы все БД имели одинаковую структуру, я бы использовал только одну базу данных и использовал идентификатор арендатора в качестве индекса, таким образом, у вас есть только одно соединение в вашем проекте, и проблема решена. В противном случае вам придется проверять все базы данных каждый раз, когда пользователь пытается войти в систему.
Все очень сильно зависит от бизнеса и типов арендаторов. В некоторых случаях ваш сценарий может работать просто отлично, в других ситуациях это может быть полной болью. Просто подумайте о случае, когда арендатор требует вернуть все свои данные? Или делать резервные копии для каждого арендатора.
где живут ваши пользователи? Возможно, вам придется извлечь информацию о пользователях в отдельную базу данных удостоверений, содержащую информацию о том, какой пользователь принадлежит какому арендатору. Это может быть так же просто, как хранилище ключей и значений: электронная почта->TenantId. Поэтому для входа в систему вам нужно будет найти это tenantId, а затем пройти аутентификацию по информации о пользователе в правильной базе данных арендатора.
Или вы можете собрать всю информацию о пользователе в единую базу данных, содержащую всю информацию о пользователе, включая хэш пароля. Вы также можете использовать какого-либо поставщика удостоверений, такого как Auth0 или IdentityServer — у них есть возможность добавлять пользовательские свойства, такие как TenantId.
Какой бы сценарий вы ни выбрали, у вас должно быть единое место, где вы сопоставляете пользователя с арендатором. Просмотр нескольких баз данных для получения информации о пользователе не идеален.
Если ваше приложение Vue.js использует ваш серверный API, вы можете установить TenantId в файле cookie или другим способом, чтобы сохранять эту информацию между вызовами.
Я думал об этом, но ваша комбинация электронной почты и пароля может быть одинаковой для более чем 1 арендатора (в каком-то диком сценарии), что тогда делать?
Если у вас есть пользователи, использующие несколько арендаторов, вам придется выполнить сопоставление «один ко многим» от пользователя к арендаторам. И когда пользователь с несколькими арендаторами входит в систему, перенаправляйте их на страницу, где они выбирают, к какому арендатору они хотели бы перейти прямо сейчас.
Мне нравится эта идея, я решил создать для этого сервер идентификации, который будет хранить и обрабатывать аутентификации пользователей, но с моим приложением, использующим собственную базу данных, как будет выполняться ссылка на пользователя? Поскольку некоторые вещи, которые хранятся в базе данных арендатора, требуют хранения для пользователя
Обычно электронная почта работает как ключ между приложениями для получения информации о пользователе на сервере идентификации и в приложении. Но Guid также будет хорошим выбором. И прежде чем реализовать свой собственный, вы видели IdentityServer.io?
Да, спасибо за рекомендацию. На самом деле я только начал изучать Identity Server. Мой вопрос: могу ли я использовать Identity Server и .NET Identity Core для одновременного управления пользователями?
То есть я не знаю, я только немного поигрался с IdentityServer. Я думаю, что будет API, который вы сможете использовать в своем приложении.
Я бы использовал подобное решение, подобное этому
https://docs.servicestack.net/мультитенантность
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 и реализовать его в своих сервисных моделях.
public interface IForTenant
{
string TenantId { get; }
}
Вам понадобится фабрика соединений с БД, которая принимает идентификатор арендатора в качестве аргумента для возврата экземпляра IDbConnection. Затем вы создаете фильтр запросов, который проверяет, относится ли запрос к типу IForTenant, и получает правильный экземпляр IDbConnection из вышеупомянутой фабрики.
Я думаю, что каждая служба, реализующая IForTenant, немного излишняя, не так ли? Действительно, соединение с БД может быть определено до того, как контроллер обработает запрос.
Вы также можете проверить заголовки запросов на наличие определенного ключа внутри ваших фильтров запросов (вы даже можете создать метод расширения для более четкого дизайна). Затем вы вводите свой IDbConnectionFactory в свои контроллеры и вызываете GetConnection(tenantId), чтобы получить соответствующее соединение. Как вы думаете?
Если у каждого арендатора своя база данных, что мешает двум арендаторам иметь пользователей с именем name? Либо пользователь должен указать идентификатор арендатора в процессе входа в систему, либо вы должны хранить всех пользователей в общей базе данных.