Рано или поздно проблема кроссдоменной авторизации встает перед всеми WEB разработчиками. Существует несколько способов организации кроссдоменной авторизации:
- через iframe;
- через javascript;
- через передачу идентификатора сессии.
Скорее всего существую и другие способы, но они меня не сильно интересуют, так как я для себя выбрал последний как самый простой в реализации и поддержке. Решение этой задачки вылилось в отдельный класс, который подключается к приложению. Помимо самого класса создается общая база данных, которая будет доступна во всех приложениях. Мы сделали отдельный проект, через который происходит регистрация и управления правами пользователей. У нас существует много внутренний приложений, для которых как раз и делали общую авторизацию, поэтому пришлось писать класс полностью универсальным, и как можно больше абстрагированным от конкретной реализации драйвера базы данных: просто подключить класс и начать пользоваться. Для начала определимся с тем, что же мы ждем:
- логин и пароль вводим одни раз, а авторизуемся в нескольких приложениях;
- гибкая система прав пользователей, основанная на группах;
- сохранение информации о сессии в базе данных.
Для выполнения первого пункта мы разработали отдельное приложение, основное назначение которого — проверить правильность ввода логина и пароля. Так же через это приложение администраторы могут добавлять новых пользователей и менять права уже имеющимся. Второй пункт немного сложнее. Мы рассматривали несколько вариантов организации хранения прав пользователей, выбирали самый простой в реализации, самый гибкий и самый легкий в поддержке. Варианты были следующие:
- для каждого отдельного права создать отдельную колонку в базе данных;
- хранить права в битовых масках, внутри приложений хранить права в виде масок для проверки;
- создать отдельную таблицу с перечнем всех прав, привязка к группе осуществляется через дополнительную таблицу (т.е. организация связи многие ко многим).
Первый сразу отмели, потому что нам в наследство достались приложения, которые как раз и хранили права в таком видел. Так что мы представляем все «удобства» такого решения. А сколько «удовольствия» доставляет добавить новые права :-). Второй вариант практические приняли как стандартный для наших приложений, но в последний момент отвергли. Да, он удобен, легко установить и удалить права, но только для одного пользователя. В случае смены прав у целой группы, надо обновлять права отдельно для всех пользователей данной группы, и одним запросом к базе данных тут не обойтись. Плюс возникают сложности, как привязать смещение в маске к отдельному праву. Еще можно только догадываться, какого размера в итоге будет маска, даже если хранить маску в разных полях базы данных для каждого приложения. Поэтому методом исключения остается последний. В нем мы нашли один недостаток, с которым может вполне мириться: сложно добавить отдельные права для каждого пользователя. Если надо расширить пользователю возможности, мы просто создаем новую группу пользователей, а потом добавляем туда всех, кому надо расширить права.
Следующим пунктом было проектирование базы данных. Но сперва надо определиться с тем, каким образом будем организовывать группы разных приложений.
Разобьем список групп на зоны. Каждая зона соответствует приложению. Внутри зоны находятся группы пользователей. Внутри группы, конечно же, находятся пользователи. Все просто и логично :-).
При создании пользователя в «админке» выставляем нужные галочки для каждого приложения (в нашем случае в каждой зоне). Все.
Просто? Для нас — да.
Теперь перейдем к самой базе данных.
Я не ручаюсь за правильность проектирования, но она решает нашу задачу в полной мере.
В таблице users хранятся учетные данные пользователей: логин, хеш пароля и настоящее имя. Отсюда пользователи не должны удаляться так как пропадут привязки к приложениям. Чтобы не держать дополнительных соединений к базе данных авторизации в приложении, мы переложили это на плечи самого MySQL сервера: для каждого приложения создали отдельные таблицы, подобные users, только тип поменяли на FEDERATED.
Назначение таблиц zones, groups, rights, по-моему, понятно из названия.
В таблице sessions хранятся сессии пользователей. Идентификация сессии проходит по хешу, который хранится в массиве $_SESSION в приложении. Так же этот хеш используется для создания собственных сессий внутри приложения.
Таблица settings хранит настройки пользователей для приложений. Например, количество пунктов списка на страницу, текущая тема приложения и т.д.
Времени особо не хватает. Поэтому пока остановлюсь на этом. Во второй части будет описание класса и исходники.
Доброго времени суток! автор, когда же будет продолжение???
Уже никогда не будет, похоже.
Сильно надо? В таком случае напишу.