Сквозная авторизация и единая база пользователей для 1.10.3

3961

Цель:

1. Единая база пользователей для нескольких сайтов (все сайты используют одну базу данных, префиксы разные)
2. Авторизовавшись на одном сайте, нужно быть автоматически авторизованным на всех остальных.
3. Отправив сообщение пользователю на первом сайте, дать ему возможность прочитать его на любом другом



Решение

1. хак файла \core\classes\db.class.php. -> Единая база пользователей
Для этого не обязательно, чтобы сайты были поддоменами - важна лишь единая база данных

2. хак файла \core\cms.php -> Единые куки для всех сайтов.
А вот для этого сайты обязательно должны быть поддоменами одного домена + сам основной домен.

Код

1. db.class.php
Добавить в блок объявлений переменных строку
Код PHP:
  1. public $users_prefix = 'my';
где "my" - это ваш префикс таблиц, в которых хранятся пользователи. Например, префикс БД для основного домена.

в метод
Код PHP:
  1. public function query($sql, $ignore_errors=false, $replace_prefix = true){
добавить после
Код PHP:
  1. $sql = $replace_prefix ? $this->replacePrefix($sql) : $sql;
строки
Код PHP:
  1.  
  2. $prefix = cmsConfig::getConfig('db_prefix');
  3. if ($this->users_prefix !== $prefix) {
  4. $sql = trim(str_replace($prefix.'_user',$this->users_prefix.'_user',$sql));
  5. }
  6.  
После этого все сайты будут обращаться к единой базе пользователей.

2. cms.php
в блок объявления переменных добавить строку
Код PHP:
  1.  
  2. private static $maindomain = '.site.ru';
  3.  
где site.ru - это ваш основной домен. Это нужно для единых кукисов.

заменить метод
Код PHP:
  1.  
  2. public static function setCookie($name, $value, $time){
  3. setcookie('InstantCMS['.$name.']', $value, $time, '/', null, false, true);
  4. }
  5.  
на
Код PHP:
  1.  
  2. public static function setCookie($name, $value, $time){
  3. setcookie('InstantCMS['.$name.']', $value, $time, '/', self::$maindomain, false, true);
  4. }
  5.  
заменить
Код PHP:
  1.  
  2. public static function unsetCookie($name){
  3. setcookie('InstantCMS['.$name.']', '', time()-3600, '/');
  4. }
  5.  
на
Код PHP:
  1.  
  2. public static function unsetCookie($name){
  3. setcookie('InstantCMS['.$name.']', '', time()-3600, '/',self::$maindomain);
  4. }
  5.  

Файлы для 1.10.3

скачать
Перед заменой - обязательно сделать копии своих файлов. Для других версий инстанта можно руками поменять код в файлах.

Пример:

1. http://izhevsk.pechenuka.ru/
2. http://sochy.pechenuka.ru/
3. http://moscow.pechenuka.ru/

Как проверить - зайти на любой сайт, авторизоваться под user1 123123 (либо зарегать нового юзера - проще всего это сделать на первом домене). Потом зайти на второй сайт уже авторизованным.
Выход из аккаунта работает после перезагрузки браузера - удаление сессий со всех сайтов не делал. То есть выходим с любого сайта, закрываем/открываем браузер и проверяем.
Парсинг и постинг для компонента InstantMaps 1.0 (бесплатная и платная версии) | Компонент "Проблемы и решения", альтернативный вариант
Комментарии (47)
Def 28 октября 2013 в 19:49 0
отличный хак!!! будет очень полезно
Endroid 28 октября 2013 в 19:53 +3
Хорошее решение! Движемся в сторону настоящего мультисайтинга?
BELIEVER 28 октября 2013 в 20:37 +2
Как всегда полезности от SJen
MauND 28 октября 2013 в 20:56 +1
Мне кажется или нужна такая вшитая фунцкия в сам движок:)
Например так как при создание англоязычной версии контент должен размещаться разные:)Следовательно базы думаю должны быть разные:)
SJen 29 октября 2013 в 05:15 0
разный контент - это не значит разные базы. Общая только база пользователей, все остальное у каждого подсайта уникальное - блоги, клубы, статьи.. Может быть на одном языке, может быть на разных.
Су-27 28 октября 2013 в 21:24 0
Спасибо - хорошее дополнение. При использовании одной базы для нескольких сайтов как сильно увеличится нагрузка на базу мускула и как вы решили проблему с синхронизацией крона, если все сайты находятся на разных серверах и в разных часовых поясах?
stealthdebuger 28 октября 2013 в 21:39 +2
Радует энтузиазм, восприимчивость к критике и желание совершенствоваться.
Считаю, что именно с таким подходом можно поднять привлекательность InstantCMS среди простых обывателей.
Спасибо за ваш труд.
SJen 29 октября 2013 в 05:21 0
При использовании одной базы для нескольких сайтов как сильно увеличится нагрузка на базу мускула
Нагрузка на сервер останется такой же. А как вы мониторите нагрузку на конкретную базу данных?
Су-27 29 октября 2013 в 08:35 0
Можно через Zabbix или через Mtop - это то что я пробовал а так утилит в сети хватает...
SJen 29 октября 2013 в 05:37 +2
как вы решили проблему с синхронизацией крона, если все сайты находятся на разных серверах и в разных часовых поясах?
Если физически база пользователей у каждого сайта своя и нужно их синхронизировать - то это совсем другая задача. Не говорю, что это нереально - реально, конечно. Просто я такой задачи перед собой не ставил. Только вот сквозной авторизации в таком случае будет непросто добиться.
tokarev 29 октября 2013 в 11:59 -1
у deltas всегда любой "сделай сам" написан понятным языком))) аццкий плюс!
tokarev 29 октября 2013 в 11:59 0
Сорри не туда...
SJen 29 октября 2013 в 12:43 +5
забавно, не правда ли? - написали не туда, а свою порцию плюсов получили rofl
lokanaft 29 октября 2013 в 12:57 0
Мало того, теперь для них автор сего не вы, а deltas)
Князь Мышкин 29 октября 2013 в 16:16 0
Как бы хорошо было, если бы сквозная авторизация была уже из коробки, а ...
alexbabo 1 ноября 2013 в 01:27 0
1 и 2 это два разных метода или надо оба файла править?
Подробнее можно инструкцию?
SJen 1 ноября 2013 в 04:04 +1
Подробная инструкция:

Вариант 1 (для 1.10.3). Скачать файлы и заменить у себя. Все.
Вариант 2 (для <1.10.3). Внести по порядку все изменения, прописанные в топике. Все.

Там две цели -
1. Единая база пользователей (правим db.class.php)
2. Сквозная авторизация (правим cms.php)

Если надо и то и другое - правим/заменяем оба файла. Если надо что-то одно - правим один файл.
alexbabo 1 ноября 2013 в 12:57 0
Спасибо SJen за пояснения.Так как я не очень разбираюсь в этом вопросе и чтобы не экспериментировать,появилось ещё пару вопросов.
В 1 и 2 случае надо файлы заменить на всех сайтах?Или только поддоменах или только на главном сайте?
И не надо вносить изменения в базу данных?Добавлять новую таблицу пользователей?

Для самопознания:
Интересно для дилетанта,я нигде не заметил обращения к определённой базе,как же распознает чужой сайт, к какой базе с нужной таблицей пользователей, подключиться?
С общей базой понятно,пользователь имеет свой профиль на каждом сайте и имеет все права.А при сквозной авторизации пользователь ,попавший с другого сайта,лимитирован в действиях?Оставив комментарий или написав пост, статью-в какой базе этот материал хранится и и кликнув по никнейму автора поста,переход будет в профиль на родной сайт пользователя?
SJen 1 ноября 2013 в 13:25 +1
Постараюсь подробно расписать
В 1 и 2 случае надо файлы заменить на всех сайтах?Или только поддоменах или только на главном сайте?
На всех сайтах, где это должно работать. Главная + поддомены, или только поддомены, или часть поддоменов - зависит от целей.

И не надо вносить изменения в базу данных? Добавлять новую таблицу пользователей?
База пользователей у вас уже есть, нужно лишь указать префикс к этой базе (public $users_prefix = 'my';). Никаких изменений дополнительно вносить не нужно. Только заменить файлы.

Интересно для дилетанта,я нигде не заметил обращения к определённой базе,как же распознает чужой сайт, к какой базе с нужной таблицей пользователей, подключиться?
База данных у всех сайтов одна, например, mybase. А вот префиксы таблиц разные. Нужно указать лишь префикс таблиц с единой базой пользователей.(public $users_prefix = 'my';). Зная этот префикс, все сайты будут использовать пользователей именно из таблиц с этим префиксом.

А при сквозной авторизации пользователь, попавший с другого сайта, лимитирован в действиях?
Не совсем понял вопрос, в чем именно лимитирован? - если пользователь в группе "Админы" - то он везде админ, если в группе "Редакторы" - то везде редактор. База юзеров единая, настройки единые.

Оставив комментарий или написав пост, статью-в какой базе этот материал хранится
Оставив коммент к статье на сайте 1, увидеть коммент можно только на сайте 1. База комментов то не единая, контент хранится на каждом сайте отдельно, в таблицах со своим префиксом.

кликнув по никнейму автора поста,переход будет в профиль на родной сайт пользователя?
У пользователя нет родного сайта, они все для него родные. Профиль будет открываться на конкретном сайте - и профиль может везде открываться по разному. В разном дизайне, с различным количеством информации.
alexbabo 1 ноября 2013 в 15:42 0
Теперь понятно,значит у каждого сайта нету отдельной базы,а одна общая.То есть при установке новой цмс,надо указывать ту же базу что и у другого сайта,но надо будет сменить префикс при инсталляции?А возможно смежить разные базы ,уже существующих сайтов, в одну базу для этих целей?Я не пробовал такого.
SJen 1 ноября 2013 в 19:09 +1
Теперь понятно,значит у каждого сайта нету отдельной базы,а одна общая.
Все верно, база одна. Это обязательное условие.

То есть при установке новой цмс,надо указывать ту же базу что и у другого сайта,но надо будет сменить префикс при инсталляции?
Точно, базу ту же. А префикс уникальный.

А возможно смежить разные базы ,уже существующих сайтов, в одну базу для этих целей?
Можно все, но непросто - точнее много надо будет исправлять в БД.
1. перенумеровывать пользователей во всех базах кроме основной (перед тем, как слить их в одну базу).
2. соответственно вносить изменения в таблицу блогов, клубов, комментов и других компонентов, в которых есть ссылка на пользователей.

Проще, конечно, изначально все делать в одной базе - вот разделить их потом (при необходимости) не проблема. А слить в одну пользователей из разных баз непросто.
alexbabo 1 ноября 2013 в 21:57 0
Спасибо за подробную информацию v
Michail 10 ноября 2013 в 17:02 0
А как будут обстоять дела с автарами пользователей? Если пользователь зарегистрировался на основном сайте или поддомене? Или в данном случае пользователь может зарегистрировать только на основном сайте?
SJen 10 ноября 2013 в 21:15 0
если ничего не делать, то отображаться аватар будет на том сайте, на котором его загрузили.. Тут надо подумать как лучще - может быть хранить в базе не локальный путь к аватару (/images/users/avatars/small/7697****.jpg), а путь с указанием домена и тогда не важно где он будет загружен
Endroid 10 ноября 2013 в 22:38 0
Точно. В идеале вообще все картинки на отдельный поддомен грузить. И на всех сайтах будут, и, говорят, производительность лучше )
Шадринец 28 ноября 2013 в 15:06 0
Я немного не понял с
Код PHP:
  1. private static $maindomain = '.site.ru';
где site.ru это мой основной домен пишется на всех поддоменнах только основной или с поддоменнами тоесть точька перед .site.ru для этого и что прописываетса на основном?
SJen 28 ноября 2013 в 17:00 0
смысл в том, что поддомены видят куки установленные для главного домена - то есть указывать надо главный домен. Даже если на нем самом вы не хотите делать сквозную авторизацию.
webscs 26 декабря 2013 в 00:00 0
Приветствую всех.

У меня вот такой вопрос: "цель: Городской порта на поддоменах, news.domen.ru, board.domen.ru и т.д. единую авторизацию на под доменах рулим хаком, а обязательно ли префиксы делать разные? ведь все что относится к новостям будет выводиться только на news.domain.ru, модуль объявления - только на board.domain.ru"

Я где то читал, что такое лучше делать изменением в настройках под доменов на серваке в аппаче. Так как будет оптимальнее?
maia 13 января 2014 в 02:45 0
А это реально сделать, если один сайт на 1.9, а другой на 1.10.3?
Greko 16 февраля 2014 в 17:19 0
Все далаю как написано, но после замены файла для единой базы пользователей, при открытии любой страницы, нет ничего, пустая страница. В чем может быть проблема?
Greko 16 февраля 2014 в 19:52 0
Затупил. С пустой страницей. А вот сделать все корректно не получаеться. Все делаю как написано но базы не клеяться. при установке нового двига в базу ложиться cms.users_users

Все делаю пошагово и ничего не происходит. Или это действует только на одинаковых версиях инстанта? У меня ода 1.10.1 а вторая 1.10.3
Greko 17 февраля 2014 в 02:17 0
Уже и переименовывал префиксы и что только не делал, не подключается к одной базе пользователей и все. Не могу понять что я делаю не так...
Greko 17 февраля 2014 в 02:35 0
А изменения в файле db.class.php приводят к пустой странице...
Greko 17 февраля 2014 в 03:25 0
Все получилось!!! Огромное спасибо!!! В том что не мог разобраться моя вина! Еще раз огромное человеческое СПАСИБО!!!
Евгений 25 февраля 2014 в 23:07 0
Подскажите, пожалуйста, как сделать общее разлогинивание.
Intrerio 25 марта 2014 в 21:02 0
Пару месяцев назад пробовал проделать процедуру соединения папок с картинками. Сделал лишь так что б фото независимо от сайта загрузки отображались на всех сайтах, но сами аватары так и не смог сделать. Может кто-то уже реализовал?
Capitan 5 апреля 2014 в 16:17 0
ну не получается и все!
1. копирую файлы в поддомен
2. прописываю префикс ОСНОВНОЙ БД
3. прописываю основной домен
и ничего не меняется
Intrerio 7 апреля 2014 в 12:34 0
Я так понимаю что тема заглохла... А все ж интересно было бы сделать сайт на котором много поддоменов со своими сайтами но модули, компоненты и даже шаблоны едины для всех и админ просто выбирает то что он хочет видеть на сайта со списка. На вордпресе реализована подобная возможность
Шадринец 30 апреля 2014 в 16:51 0
Я тоже присоединяюсь к теме Может будет продолжение,Как написано все поставил, работает авторизация и регистрация,хотелось бы обобщить аватарки личные фото .
Nikit 30 августа 2014 в 13:42 0
Спасибо. Сейчас думаю над этой проблемой. А здесь почти готовое решение.
Александр 7 января 2015 в 15:55 0
Есть кто живой кто проделывал процедуру? может сталкивались с таким моментом, версия 1.10.4 (вероятно неважно какая версия движка), проделал на домене и поддомене, в результате если авторизуешься на домене, то поддомен куки видит и ты там тоже авторизован, если сначала на поддомене авторизуешься, то домен этого не видит, в остальном все работает.

и кстати в примере только 1 и 3 ссылка куки воспринимает.
Александр 8 января 2015 в 10:28 0
И то это работает только в последнем IE , в других браузерах не передаются куки, видимо произошло глобальное какоето изменение в правилах безопасности браузеров или как то так...
broman 6 марта 2015 в 21:24 0
а на instantcms 2.1.2 будет работать?
broman 6 марта 2015 в 21:24 0
а на instantcms 2.1.2 будет работать?
Ї Ђãîķℳāŋ Ї 17 мая 2015 в 20:08 +1
Лови +
sosed 11 апреля 2016 в 07:19 0
А для InstantCMS 2.x можете подобное объединение сделать?
DeusSpa 14 октября 2017 в 17:54 0
Всем доброго времени суток.
Если подобное решения для объединения базы пользователей?
И синхрона авторизации, с главный сайт на 2 ветке, поддомен на 1 ветке.