Вопрос или проблема
В настоящее время я (зло)использую oauth2 конечную точку API, чтобы позволить пользователям API входить на мой сайт (используя response_type=code
). Я не сохраняю refresh токены или даже access_token
, так как эта oauth2 конечная точка не поддерживает области и я хочу минимизировать опасности украденных аккаунтов.
Oauth2 конечная точка успешно перенаправляет на мою страницу аутентификации (PHP), если пользователь уже предоставил мои client_id permissions
и уже вошел в систему через этот сервис. Это произойдет без взаимодействия с пользователем. Моя страница аутентификации установит некоторые сеансовые переменные и перенаправит на соответствующую страницу.
Сессия на моем сервере может истечь, когда пользователь только что создал много данных и хочет их сохранить (через AJAX). Поэтому я хочу автоматически повторно аутентифицировать пользователя через поставщика oauth2 (в случае, если сессия все еще активна) без отправки его на серию перенаправлений.
Таким образом, идея состоит в следующем:
- Если пользователю, который однажды вошел в систему, нужно повторно пройти аутентификацию, я создаю изображение с слушателем
onload
/onerror
, указывающим на мою конечную точку аутентификации. - Моя конечная точка аутентификации затем перенаправит на oauth2 конечную точку, которая в свою очередь перенаправляет обратно на мой сайт аутентификации, если пользователь уже предоставил разрешения.
- Моя конечная точка аутентификации обновляет сессию и возвращает одноточечное изображение, если аутентификация прошла успешно. В противном случае – нет.
- Если событие
image.onload
сработает на стороне клиента иimage width * height == 1
, пользователь повторно аутентифицирован. - Если сработает событие
onerror
илиwidth*height != 0
, потребуется взаимодействие с пользователем.
Есть ли какие-либо потенциальные проблемы, которые я мог упустить, и/или существует ли эта схема?
Насколько я вижу, таким образом мы создадим еще один запрос к oauth2 конечной точке, если сессия пользователя у поставщика oauth2 истекла / разрешение было отозвано. С другой стороны, если пользователь все еще аутентифицирован, нам не нужны дополнительные запросы, и пользователю не нужно загружать весь CSS+JS oauth2 конечной точки.
В целом, ваш подход очень интересен, но есть несколько моментов, на которые вам определенно следует обратить внимание.
В качестве варианта вы можете использовать iframe для “тихой” аутентификации. Что-то вроде: <iframe src="/auth/silent" style="display:none;"></iframe>
Конечная точка /auth/silent
инициирует процесс аутентификации и обновляет сессию пользователя.
Для проверки сессии мы можем использовать AJAX-запросы для контроля над процессом. Плюс, в идеале, безопасно хранить refresh_token
, чтобы получить новый access_token
без необходимости повторной аутентификации пользователя.
Ответ или решение
Ваш подход к автоматической реаутентификации пользователя через OAuth2 выглядит достаточно интересным, однако есть несколько важных моментов, на которые стоит обратить внимание.
Основные проблемы и рекомендации:
-
Использование Iframe для "тихой" аутентификации:
Вместо загрузки изображения с обработчикамиonload
иonerror
, вы можете рассмотреть возможность использования iframe для "тихой" аутентификации. Например, вы можете создать iframe с URL, указывающим на ваш эндпоинт аутентификации:<iframe src="/auth/silent" style="display:none;"></iframe>
Этот эндпоинт будет инициировать процесс аутентификации и обновлять сессию пользователя без необходимости перенаправления его на страницу входа.
-
Проверка сессии:
Рекомендуется использовать AJAX-запросы для проверки сессии пользователя. Это позволит вам более гибко управлять аутентификацией и проверять состояние сессии без таких манипуляций, как создание изображения. -
Безопасное хранение refresh_token:
Хотя вы не используете refresh_token в данный момент, подумайте о внедрении механизма его безопасного хранения. Это позволит вам получать новые access_token, не требуя от пользователя повторной аутентификации, что значительно улучшит пользовательский опыт. -
Обработка неудачных аутентификаций:
Вам необходимо корректно обрабатывать ситуации, когда аутентификация не удалась (например, при истечении срока действия сессии или отзыве разрешений). Пользователь должен быть информирован о необходимости вручную войти в систему, и вы можете добавить стратети для отображения соответствующего уведомления. -
Производительность и эффект пользователи:
Будьте внимательны к минимизации числа запросов к OAuth2-provider. Если пользователи часто инициируют восстановление сессии, это может привести к избыточному количеству запросов, что может вызвать потенциальные ограничения со стороны API-поставщика. Постарайтесь оптимизировать ваш способ проверки состояния сессии. -
Соответствие требованиям безопасности:
Обязательно проанализируйте, как ваша система защиты обрабатывает потенциальные атаки, такие как CSRF или XSS. Несмотря на то, что вы стремитесь минимизировать риски, необходимые меры безопасности должны быть реализованы на всех уровнях вашего приложения.
Заключение
Ваш метод может работать, но вам необходимо будет учитывать все вышеперечисленные аспекты. Использование iframe для "тихой" аутентификации представляет собой элегантное решение. Вместо того, чтобы полагаться на изображение, которое вызывает больше проблем, использовала AJAX-запросы и, возможно, пересмотреть вашу стратегию управления токенами аутентификации – это позволит вашему приложению работать более эффективно и безопасно.