Есть одно веб-приложение, в которое логинятся пользователи и в нём работают. Пишется другое приложение, в которое уже залогинненные в первом приложении юзеры будут периодически заходить. Как _безопасно_ передать из первого приложения во второе, что юзер "ААА" уже залогинился в первом приложении и ему ещё раз логиниться во втором не нужно. Оба приложения - на PHP, расположены на одном сервере как разные виртуал-хосты.
А попроще есть варианты? Пользователь авторизовался в первом приложении (уже написанном и работающем, и хочется минимальных изменений). И по кнопочке/ссылочке переходит в другое приложение - нужно передать UserID, и что он уже авторизован.
Нужно для перехода в другое приложение генерировать ссылку с одноразовым токеном. Чтобы приложение 2 могло определить пользователя по токену, ему должна быть доступна таблица токенов. Эта схема достаточно безопасна, если вы используете https.
- дай мне карандаш - держи - но он красный! - а ты какой хотел? - простой - а красный для тебя слишком сложно? Ты сейчас зачем-то отказываешься от того, что хочешь. У тебя есть два сайта, лежат на одном серваке. Сессия у каждого сайта будет разная ибо протокол. Но ты можешь в хранилище разместить какой-то токен, редиректнують юзера на этот токен, выхватить на другом сайте из этого токена привязку к существующей "сессии" и продолжить сеанс. Этот фокус и называется SSO. Если будет несколько серверов и сервисов - тогда система будет немного сложнее. Там появятся всякие брокеры авторизации. Но это будет тот же ССО. В общем юзай.
Дело в том, что описание SSO на wiki существенно отличается от варианта с токеном - поэтому я и поинтересовался вариантом попроще. Вариант с одноразовым токеном - намного проще. Тем более, мне даже нет необходимости передавать сессию - достаточно в первом приложении сгенерировать токен и сохранить его в БД, указав, для какого UserID этот токен сгенерирован, а второе приложение, получив токен, "узнает" UserID из БД по токену. Огромное спасибо тебе и [vs] за идею. Осталось только продумать механизм "устаревания" токенов (при переходе во второе приложение токен нельзя считать устаревшим, т.к. такие переходы теоретически могут выполняться несколько раз при открытой (не обновляемой) странице в первом приложении). По большому счёту, токен, сгенерированный более 24 часов назад, можно смело считать устаревшим.
токен вообще-то одноразовый должен быть. перекинули, сопроводив токеном, активировали связанную сессию, и удалили токен
вот представь - открыта страница в первом приложении со ссылкой на второе приложение. я кликаю по ссылке и перехожу (второе приложение открывается в новой вкладке или в новом окне), ссылка остается неизменной. я поработал во втором приложении и закрыл его. страница в первом приложении так и открыта, и я через N часов снова хочу перейти по ссылке - а токен уже недействителен... Или я недопонял идею с токеном?
Ссылка на второе приложение должна быть без токенов. Ткнув по ней - браузер уходит ко второму приложению. Там он обменивается своими заголовками, среди которых будут и печеньки. Завидев анонима, второе приложение редиректит юзера к гейту ССО, не забыв добавить возвратную информацию. Гейт ССО проверяет собственно залогинен ли пользователь, и, если да - регистрирует в "сессии" токен для второго приложения. После этого гейт редиректит пользователя обратно ко второму приложению, указав токен и возвратку. Встретив токен второе приложение цепляется к "сессии" и потом обрабатывает "исходный" запрос, но с уже известным пользователем. Ну и, соответственно, если сеанс у пользователя еще не завершился, то ткнув по ссылке из первого приложения и перейдя во второе - пользователь просто продолжит работу без лишних редиректов. Сессия тут в кавычках потому, что стандартный механизм сессий для таких дел уже не подходит - нужно будет реализовать некоторое хранилище для нужд ССО.
А где-то есть детальное описание этого механизма? А то я чем больше перечитываю - тем больше вопросов... Кто выполняет функции гейта? Откуда гейт узнает, что юзер залогинен в первом приложении? 1-е приложение при авторизации выбирает из БД хэш пароля по логину и сравнивает с хешем введённого пароля. совпали - юзер залогинен (признак сохраняем в сессии). Никакие сторонние приложения для авторизации не используются. Даже если я в 1-м приложении буду отмечать в БД, что юзер залогинен - как я узнаю, что он всё ещё залогинен (кнопкой "Выход" никто не пользуется - закрывается либо браузер, либо вкладка).
Детальное описание должно быть в голове у программиста. Это всего лишь такой же алгоритм, который решает какую-то конкретную задачу, манипулируя какими-то данными. Функции гейта выполняет один скрипт расположенный либо в первом (в твоем случае) приложении или на отдельном хосте (в универсальных ссо). Гейт узнает что пользователь залогинен потому что когда к нему (а он у тебя на хосте первого приложения лежит) идет запрос - идут и куки, по которым твоё первое приложение узнает, что юзер залогинен. В случае с выделенным хостом тоже ровно ноль проблем - юзер будет залогинен именно на ссо-гейте, а все приложения - одно, два, миллиард - будут знать эту же информацию, но через бэкэнд. Если у тебя юзер где-то нажал кнопку выхода, то ты можешь убить признак в "сессии", что опять же совсем не зависит от реализации - скрипт на первом приложении или отдельностоящий брокер.