Как я могу разрешить пользователям регистрироваться в одном домене и автоматически регистрироваться в других доменах без необходимости отправки формы в каждый домен?
Междоменный вход с использованием JSONP и файлов cookie
Ответ 1
Мы все знаем, что файлы cookie недоступны для междоменного доступа, так как это представляет угрозу безопасности. Однако, используя некоторые обманки, есть способы обойти это. В основном мы устанавливаем cookie для пользователя в центральном домене, проверяя существование этого файла cookie с помощью script, а затем используя обратный вызов JSON-P для копирования этого файла cookie на другие домены. Подробнее:
Вход в систему
Шаг 1
<form>
, отображаемый на mydomain.com
(или myotherdomain.com
и т.д.), должен быть POST до central.com/login
Шаг 2
В central.com/login
имя пользователя и пароль проверены, а cookie установлен в домене central.com
, содержащем уникальное значение для этого пользователя. Затем пользователь перенаправляется обратно на mydomain.com
SELECT unique_value FROM users WHERE username = $username
set cookie on central.com containing unique_value
Шаг 3
Вернемся к mydomain.com
, мы вставляем javascript-вызов в central.com/check
.
<script type="text/javascript" src="http://central.com/check"></script>
Шаг 4
В central.com/check
мы проверяем, установлен ли для пользователя уникальный cookie. Затем мы встраиваем обратный вызов JavaScript (JSON-P), который информирует mydomain.com
о том, что пользователь вошел в систему. Не включены никакие конфиденциальные данные пользователя, иначе hacker.com
может вставить этот script и получить информацию о пользователе. (Установка соответствующих заголовков Access-Control для разрешения разрешенных доменов может облегчить этот риск.) Вместо этого мы создаем одноразовый хеш на основе временной метки, чтобы mydomain.com
мог проверить подлинность.
if cookie on central.com is valid
user_data = array(
'success' => true,
'uid' => $uid,
'time' => time_stamp,
'hash' => disposable_salted_hash( $uid, time_stamp )
)
echo 'setDomainCookie(' . json_encode(user_data) . ')'
Шаг 5
Затем выполняется функция обратного вызова, установив файл cookie на mydomain.com
. Наконец, мы можем либо обновить страницу, либо просто предупредить пользователя, используя JavaScript, в котором они вошли (желательно оба).
function setDomainCookie( user_data ) {
if( user_data.success ) {
$.post('/setcookie', user_data, function() {
location.reload(true);
}
}
}
mydomain.com/setcookie
похож на Шаг 2. Конечно, это предполагает, что оба сайта имеют доступ к одной и той же базе данных (и коду)
if hash = disposable_salted_hash( $uid, time_stamp )
SELECT unique_value FROM users WHERE uid = $uid
set cookie on mydomain.com containing unique_value
Шаг 6
В следующий раз, когда пользователь обновит страницу, мы можем обойти обратный вызов JSON-P
if cookie on mydomain.com is valid
loggedin = true
else
delete cookie on mydomain.com
proceed to Step 3
Выход из системы
Шаг 7
Ссылка на mydomain.com
должна перейти к central.com/logout
Шаг 8
В central.com/logout
удаляется не только файл cookie, но и уникальное значение для этого пользователя reset. Пользователь перенаправляется обратно на mydomain.com
delete cookie on central.com
UPDATE users SET unique_value = new_random_value() WHERE username = $username
Шаг 9
Теперь, когда уникальное значение reset, Шаг 6 сверху не работает, файл cookie также удаляется из mydomain.com
, и пользователь фактически вышел из системы.
Примечания
-
Очень важно, чтобы
central.com/check
от Шаг 4 имел правильный набор заголовков, чтобы он не был кеширован. -
Шаги 3-5, когда пользователь регистрируется, могут вызвать небольшую задержку. Разумно как обновить, так и показать какое-то напоминание о том, что они вошли в систему. Важно также, чтобы script от Шаг 3 был как можно ближе к верхней части страницы.
-
В Шаге 5 вы можете дополнительно сохранить уникальное значение cookie для каждого домена.
-
Отдельный домен
central.com
не нужен; ты можешь просто используйте один из других доменов в качестве центрального домена, если хотите. Логика для этого домена, очевидно, была бы иной. -
Для этого в Internet Explorer вам понадобится политика P3P прикрепленных к вашим файлам cookie.
-
Как отмечает ИванГусев в комментариях, один из недостатков этого подхода заключается в том, что если пользователь выходит из устройства A, он также выведет их из любого другого устройства.
-
Надеюсь, это полезно людям. Мне было бы очень интересно получить обратной связи, особенно если есть какие-либо недостатки безопасности из этого метод. Я думаю, худшее, что может сделать хакер, это повторить шаги 3-5 и войти в
mydomain.com
, не зная, но это было бы безвредно.