Кроссдоменная авторизация: часть 1

Рано или поздно проблема кроссдоменной авторизации встает перед всеми WEB разработчиками. Существует несколько способов организации кроссдоменной авторизации:

  1. через iframe;
  2. через javascript;
  3. через передачу идентификатора сессии.

Скорее всего существую и другие способы, но они меня не сильно интересуют, так как я для себя выбрал последний как самый простой в реализации и поддержке. Решение этой задачки вылилось в отдельный класс, который подключается к приложению. Помимо самого класса создается общая база данных, которая будет доступна во всех приложениях. Мы сделали отдельный проект, через который происходит регистрация и управления правами пользователей. У нас существует много внутренний приложений, для которых как раз и делали общую авторизацию, поэтому пришлось писать класс полностью универсальным, и как можно больше абстрагированным от конкретной реализации драйвера базы данных: просто подключить класс и начать пользоваться. Для начала определимся с тем, что же мы ждем:

  1. логин и пароль вводим одни раз, а авторизуемся в нескольких приложениях;
  2. гибкая система прав пользователей, основанная на группах;
  3. сохранение информации о сессии в базе данных.

Для выполнения первого пункта мы разработали отдельное приложение, основное назначение которого — проверить правильность ввода логина и пароля. Так же через это приложение администраторы могут добавлять новых пользователей и менять права уже имеющимся. Второй пункт немного сложнее. Мы рассматривали несколько вариантов организации хранения прав пользователей, выбирали самый простой в реализации, самый гибкий и самый легкий в поддержке. Варианты были следующие:

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

Первый сразу отмели, потому что нам в наследство достались приложения, которые как раз и хранили права в таком видел. Так что мы представляем все «удобства» такого решения. А сколько «удовольствия» доставляет добавить новые права :-). Второй вариант практические приняли как стандартный для  наших приложений, но в последний момент отвергли. Да, он удобен, легко установить и удалить права, но только для одного пользователя. В случае смены прав у целой группы, надо обновлять права отдельно для всех пользователей данной группы, и одним запросом к базе данных тут не обойтись. Плюс возникают сложности, как привязать смещение в маске к отдельному праву. Еще можно только догадываться, какого размера в итоге будет маска, даже если хранить маску в разных полях базы данных для каждого приложения. Поэтому методом исключения остается последний. В нем мы нашли один недостаток, с которым может вполне мириться: сложно добавить отдельные права для каждого пользователя. Если надо расширить пользователю возможности, мы просто создаем новую группу пользователей, а потом добавляем туда всех, кому надо расширить права.

Следующим пунктом было проектирование базы данных. Но сперва надо определиться с тем, каким образом будем организовывать группы разных приложений.

Разобьем список групп на зоны. Каждая зона соответствует приложению. Внутри зоны находятся группы пользователей. Внутри группы, конечно же, находятся пользователи. Все просто и логично :-).

При создании пользователя в «админке» выставляем нужные галочки для каждого приложения (в нашем случае в каждой зоне). Все.

Просто? Для нас — да.

Теперь перейдем к самой базе данных.

Я не ручаюсь за правильность проектирования, но она решает нашу задачу в полной мере.

В таблице users хранятся учетные данные пользователей: логин, хеш пароля и настоящее имя. Отсюда пользователи не должны удаляться так как пропадут привязки к приложениям. Чтобы не держать дополнительных соединений к базе данных авторизации в приложении, мы переложили это на плечи самого MySQL сервера: для каждого приложения создали отдельные таблицы, подобные users, только тип поменяли на FEDERATED.

Назначение таблиц zones,  groups, rights, по-моему, понятно из названия.

В таблице sessions хранятся сессии пользователей. Идентификация сессии проходит по хешу, который хранится в массиве $_SESSION в приложении. Так же этот хеш используется для создания собственных сессий внутри приложения.

Таблица settings хранит настройки пользователей для приложений. Например, количество пунктов списка на страницу, текущая тема приложения и т.д.

Времени особо не хватает. Поэтому пока остановлюсь на этом. Во второй части будет описание класса и исходники.

3 комментария к “Кроссдоменная авторизация: часть 1”

  1. Доброго времени суток! автор, когда же будет продолжение???

Оставьте комментарий

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.