Есть несколько веб-приложений, каждое приложение расположено на отдельном субдомене одного и того же домена второго уровня (site.com). Нужно реализовать сквозную аутентификацию пользователей: если пользователь вошел на одном из сайтов, ему не нужно входить на всех остальных (наподобие того, как это сделано у Яндекса или Гугла, например).
Было решено вынести работу с учетными записями и профилями на отдельный (центральный) сайт: если пользователь нажимает кнопку "Войти" на sub.site.com, его редиректит на site.com, после аутентификации site.com устанавливает cookie (которая доступна всем субдоменам site.com) и редиректит пользователя обратно.
Проблема в том, что в некоторых приложениях отображаются данные из профилей пользователей: например, имя пользователя рядом с его комментарием (до 1000 комментариев на странице). Поскольку пользователь редактирует свое имя на site.com, то приложение на sub.site.com ничего об этом не знает и продолжает отображать прежнее (закэшированное) имя. Я сейчас хожу и думаю, как бы реализовать синхронизацию этих данных, с архитектурной точки зрения.
Варианты, которые я пока придумал:
После редактирования профиля отправлять server-to-server запрос (например, REST или SOAP) от site.com на все субдомены.
Минусы: придется реализовать этот механизм во всех приложениях; это может снизить производительность редактирование профиля с точки зрения пользователя; проблемы, если какой-то из сайтов в этот момент офлайн.
Делать периодический server-to-server pull-запрос от всех приложений к site.com для проверки на наличие изменений и синхронизации.
Минусы: раз периодический, это означает задержку в синхронизации и соответствующие жалобы пользователей: "Я поменял имя, а в комментарии оно не обновилось".
В базах данных приложений хранить только идентификаторы пользователей, а для отображения имен рядом с комментариями делать кросс-серверный JOIN-запрос между БД приложения и БД site.com.
Минусы: ссылочная целостность, вроде как, не поддерживается (хотя это не такой большой минус, по сравнению с другими вариантами). Ну и производительность, конечно.
Хранить данные всех приложений в одной базе.
Минусы: неудобства во время разработки и деплоймента БД (инструменты для деплоймента удаляют из БД все таблицы, которых нет в проекте, так что придется все вести в одном проекте). В будущем, возможно, разные проекты будут на разных хостингах, а открывать БД в интернет или городить VPN не хочется.
Почитать про репликацию БД (MS SQL). Посмотреть, поможет ли.
Минусы: никогда не делал репликацию БД. Даже не знаю, помогает ли она в этом случае.
Разместить все веб-приложения на одном сервере и сделать какой-нибудь специальный костыль, вроде кросс-процессного shared memory (если это имеет значение, то все приложения на ASP.NET MVC, ОС Windows).
Минусы: костыль, сложности в масштабировании, проблемы с несколькими хостингами.
Есть ли какие-то еще варианты?
PS. Если ничего не понятно из того, что я написал, то вот простая аналогия: аутентификация на сайте через OAuth, например, через ВКонтакте: сайт достает имя аутентифицировавшегося пользователя и отображает его рядом с его комментариями на сайте -> через день пользователь меняет свое имя во Вконтакте, но сайт об этом ничего не знает и продолжает отображать старое имя. Отличие моей ситуации в том, что центральный сайт с профилями (ВКонтакте в этом примере) разрабатываю тоже я, поэтому могу сделать в нем все, что хочу.
Re: Централизованное хранение профилей и их синхронизация
Здравствуйте, vers, Вы писали:
V>Есть несколько веб-приложений, каждое приложение расположено на отдельном субдомене одного и того же домена второго уровня (site.com). Нужно реализовать сквозную аутентификацию пользователей: если пользователь вошел на одном из сайтов, ему не нужно входить на всех остальных (наподобие того, как это сделано у Яндекса или Гугла, например). V>Было решено вынести работу с учетными записями и профилями на отдельный (центральный) сайт: если пользователь нажимает кнопку "Войти" на sub.site.com, его редиректит на site.com, после аутентификации site.com устанавливает cookie (которая доступна всем субдоменам site.com) и редиректит пользователя обратно. V>Проблема в том, что в некоторых приложениях отображаются данные из профилей пользователей: например, имя пользователя рядом с его комментарием (до 1000 комментариев на странице). Поскольку пользователь редактирует свое имя на site.com, то приложение на sub.site.com ничего об этом не знает и продолжает отображать прежнее (закэшированное) имя. Я сейчас хожу и думаю, как бы реализовать синхронизацию этих данных, с архитектурной точки зрения.
V>Варианты, которые я пока придумал:
V>[list=1] V>После редактирования профиля отправлять server-to-server запрос (например, REST или SOAP) от site.com на все субдомены. V> Минусы: придется реализовать этот механизм во всех приложениях; это может снизить производительность редактирование профиля с точки зрения пользователя; проблемы, если какой-то из сайтов в этот момент офлайн.
Это не самый худший вариант, т.к. редактирование профиля не самая частая операция.
V>Делать периодический server-to-server pull-запрос от всех приложений к site.com для проверки на наличие изменений и синхронизации. V> Минусы: раз периодический, это означает задержку в синхронизации и соответствующие жалобы пользователей: "Я поменял имя, а в комментарии оно не обновилось".
Это, кмк, вообще бред.
V>Почитать про репликацию БД (MS SQL). Посмотреть, поможет ли. V> Минусы: никогда не делал репликацию БД. Даже не знаю, помогает ли она в этом случае.
Почитать всегда полезно, но как это поможет в Вашем случае я Мож MS SQL умеет как-то реплицировать отдельные таблицы, если в них были изменения.
V>Есть ли какие-то еще варианты?
V>PS. Если ничего не понятно из того, что я написал, то вот простая аналогия: аутентификация на сайте через OAuth, например, через ВКонтакте: сайт достает имя аутентифицировавшегося пользователя и отображает его рядом с его комментариями на сайте -> через день пользователь меняет свое имя во Вконтакте, но сайт об этом ничего не знает и продолжает отображать старое имя. Отличие моей ситуации в том, что центральный сайт с профилями (ВКонтакте в этом примере) разрабатываю тоже я, поэтому могу сделать в нем все, что хочу.
Вообще говоря, один update должен все сделать. Т.е. при построении страницы данные из базы считываются, соотв. задача в консистентном обновлении баз(ы). Я думаю MS SQL это умеет. На прикладном уровне городить ничего не следует. Только работа с базой данных. Ну т.е., если пользователь увидел свой старый ник в комментариях, то F5 должно ситуацию исправилть.
Кодом людям нужно помогать!
Re: Централизованное хранение профилей и их синхронизация
Здравствуйте, vers, Вы писали:
V>Проблема в том, что в некоторых приложениях отображаются данные из профилей пользователей: например, имя пользователя рядом с его комментарием (до 1000 комментариев на странице). Поскольку пользователь редактирует свое имя на site.com, то приложение на sub.site.com ничего об этом не знает и продолжает отображать прежнее (закэшированное) имя. Я сейчас хожу и думаю, как бы реализовать синхронизацию этих данных, с архитектурной точки зрения.
А много ли их, этих данных? А то, может прям в куку их закодировать?
Re[2]: Централизованное хранение профилей и их синхронизация
Здравствуйте, Sharov, Вы писали:
V>>После редактирования профиля отправлять server-to-server запрос (например, REST или SOAP) от site.com на все субдомены. V>> Минусы: придется реализовать этот механизм во всех приложениях; это может снизить производительность редактирование профиля с точки зрения пользователя; проблемы, если какой-то из сайтов в этот момент офлайн.
S>Это не самый худший вариант, т.к. редактирование профиля не самая частая операция.
Да, Вы правы, редактирование профиля не частая операция.
И да, похоже, это будет самый оптимальный вариант по соотношению затраты / удобство, возьму его за основу.
Re[2]: Централизованное хранение профилей и их синхронизация
Здравствуйте, Pzz, Вы писали:
V>>Проблема в том, что в некоторых приложениях отображаются данные из профилей пользователей: например, имя пользователя рядом с его комментарием (до 1000 комментариев на странице). Поскольку пользователь редактирует свое имя на site.com, то приложение на sub.site.com ничего об этом не знает и продолжает отображать прежнее (закэшированное) имя. Я сейчас хожу и думаю, как бы реализовать синхронизацию этих данных, с архитектурной точки зрения.
Pzz>А много ли их, этих данных? А то, может прям в куку их закодировать?
Данных, действительно, не много, но если их передавать через cookie, то это не сработает вот в таком сценарии:
Пользователь размещает комментарий на sub.site.com.
Пользователь меняет имя в своем профиле на site.com -> обновленный профиль записывается в cookie.
Пользователь не возвращается обратно на sub.site.com, следовательно sub.site.com не узнает об изменениях и продолжает показывать старое имя напротив комментария пользователя.
Re[3]: Централизованное хранение профилей и их синхронизация
Здравствуйте, vers, Вы писали:
V> V>Пользователь размещает комментарий на sub.site.com. V>Пользователь меняет имя в своем профиле на site.com -> обновленный профиль записывается в cookie. V>Пользователь не возвращается обратно на sub.site.com, следовательно sub.site.com не узнает об изменениях и продолжает показывать старое имя напротив комментария пользователя. V>
В принципе, такое поведение можно считать осмысленным. Например, был такой мальчих Вася, писал сообщения, потом сменил пол и стал девочкой Машей. Соответственно, старые сообщения подписаны именем Вася, новые — именем Маша. Вполне, по-моему, логично.
Если это не устраивает, тогда проще всего профили хранить в общей для всех сайтов базе.
Re: Централизованное хранение профилей и их синхронизация
Здравствуйте, vers, Вы писали:
V>Есть ли какие-то еще варианты?
Самый очевидный — распределенный кэш или nosql-база с репликацией (репликация средствами SQL Server из этой же оперы).
Варианты с ручной синхронизацией, ИМХО, более геморные и смахивают на изобретение велосипедов.
Re[2]: Централизованное хранение профилей и их синхронизация
Здравствуйте, Lexey, Вы писали:
V>>Есть ли какие-то еще варианты?
L>Самый очевидный — распределенный кэш или nosql-база с репликацией (репликация средствами SQL Server из этой же оперы). L>Варианты с ручной синхронизацией, ИМХО, более геморные и смахивают на изобретение велосипедов.
Да, мне тоже этот вариант (распределенный кэш) пришел в голову первым, я даже посмотрел/почитал тьюториалы по NCache и AppFabric, но в результате (основываясь только на своем субъективном ощущении) решил, что это будет как из пушки по воробьям.
Возможно, когда-нибудь в будущем, когда проекты разрастутся настолько, что станет нерационально хостить их на одном сервере... Или если вдруг понадобится синхронизация чего-то еще помимо профилей.