Pull to refresh

Межсайтовая авторизация 2

Website development *
По итогам поста, сделанного в июле 2009 и продолжительным испытаниям, мы пришли к простой и оптимальной для нас схеме межсайтовой авторизации.

Задача — организовать межсайтовую авторизацию между проектами, размещенными на разных доменах (site1.com, site2.com). Пользователь автризовавшись на одном проекте, получает авторизацию на всех (Single Sign On). Тоже самое с кнопкой выход (Single Sign Out). Доступ к хранилищу сессий и к базе есть у каждого проекта. На обоих проектах авторизация не обязательна.
Хочу подчеркнуть что вопросы регистрации, хранения и передачи пользовательских данных сейчас не обсуждаются, интересует только авторизация.

Задачу можно разделить на три основных части:
  1. Авторизация — пользователь ввел логин и пароль в форме.
  2. Автоматическая авторизация — пользователь нажал «запомнить меня», или уже авторизован на одном из проектов.
  3. Выход — пользователь нажал кнопку «выход».

Договоримся, что:
  • site.com — один из проектов.
  • sso.com — сервер общей авторизации.

Авторизация


Пользователь на site.com заполняет форму. Мы шифруем в одну строку (токен) и передаем редиректом на sso.com:
  • Логин.
  • Пароль.
  • «Запомнить меня».
  • url1 — адрес на который должны вернуться, если авторизация прошла успешно.
  • url2 — адрес на который мы переходим, если ошибка.
  • Текущее время — для проверки на устаревание токена.
sso.com принимает GET запрос, расшифровывает данные и проверяет время создания токена (не более 2 минут) и логин/пароль:
  • Логин/пароль верный: на sso.com создаем сессию и cтавим cookie. Сохраняем связь ID сессии и ID пользователя в базе. Делаем редирект на url1 с зашифрованными ID сессии и «запомнить меня». На site.com подцепляем сессию и ставим cookie.
  • Логин/пароль не верный: делаем редирект на url2.

Автоматическая авторизация


Пользователь заходит на site.com. Проверяем сессионную cookie:
  • Cессионная cookie есть: проверяем есть ли сессия
    • Сессия есть: пользователь авторизован!
    • Сессии нет: проверяем в базе есть ли связка ID сессии и ID пользователя:
      • Связка есть: поднимаем сессию и пользователь авторизован!
      • Связки нету: удаляем сессионную cookie на site.com.
  • Сессионной сookie нет: вставляем javascript файл c sso.com в начале страницы. Файл отдается PHP скриптом, который проверяет есть ли cookie на sso.com:
    • Cookie есть: проверяем поднята ли сессия
      • Сессия поднята: пишем в JS установку сессионной cookie и перезагрузку страницы на site.com. Пользователь авторизован!
      • Сессия не поднята: проверяем есть ли привязка ID сессии к ID пользователя
        • Cвязь есть: поднимаем сессию и возращаем в JS установку cookie и перезагрузку страницы на site.com. Пользователь авторизован!
        • Связи нет: удаляем cookie и возвращаем пустой JS.
    • Cookie нет: возвращаем пустой JS.

Выход


Пользователь на site.com жмет на кнопку «выход». Опускаем сессию, удаляем сессионную cookie и делаем редирект на sso.com с зашифрованным обратным адресом. sso.com удаляет сессионную cookie и связь ID сессии с ID пользователя в базе. Пользователь вышел!

Как вы понимаете это схема работает с любым количеством проектов. Пользователь авторизовавшись на одном из них, будет авторизован на всех. Тоже самое с кнопкой «выход».

Буду рад, если наш опыт будет вам полезен. Конструктивная критика приветствуется.

Update: Спасибо DileSoft и divedeep за ценные замечания, которые учел в этой схеме.
Tags:
Hubs:
Total votes 51: ↑41 and ↓10 +31
Views 23K
Comments Comments 61