Создание аккаунта OAuth не удаётся из-за обнаружения CSRF сразу после входа в Auth0 в том же браузере

Мы настроили плагин oauth2 в соответствии с инструкциями в статье Настройка регистрации и входа с помощью Auth0 через базовый плагин OAuth2.

Процесс выглядит следующим образом:

  • Пользователи регистрируются на странице https://getdbt.com/community/join-the-community
  • Им приходит письмо с подтверждением от Auth0
  • Они попадают на страницу https://getdbt.com/community/email-verified
  • Они нажимают Получить помощь на форуме сообщества и перенаправляются в Auth0 для входа
  • После входа их перекидывает на discourse.getdbt.com, но отображается предупреждение о CSRF.

Если они нажмут Войти, а затем Использовать учётную запись dbt Community, учётная запись будет успешно создана, и они увидят диалог создания аккаунта, где смогут задать имя пользователя и другие данные.

Видео Loom, демонстрирующее этот процесс:

Я включил oauth2 debug auth и в логах вижу сообщение (oauth2_basic) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected.

Мои вопросы:

  1. Это проблема Discourse или Auth0? Я предполагаю, что Discourse, поскольку практически идентичный процесс входа для Slack работает без проблем.
  2. Почему это работает на странице входа, но не срабатывает, когда вход инициируется со стороны Auth0?
  3. Сообщение об ошибке CSRF по умолчанию подразумевает, что она возникает при смене браузера или если процесс входа занимает слишком много времени. Ни то, ни другое не имеет места, что ещё может быть причиной?

Привет, @joellabes! Пожалуйста, проверь, какой URL указан в настройке Auth0 «Application Login URI»!

Там должно быть {your forum}/auth/oauth2_basic. Если в конце указан /callback, это может вызвать описанную тобой проблему.

Спасибо, @david — сейчас в поле URI входа в приложение у меня ничего нет, но в поле разрешённых URL обратного вызова что-то указано:

Мне следует указать https://discourse.getdbt.com/auth/oauth2_basic в поле URI входа в приложение и оставить https://discourse.getdbt.com/auth/oauth2_basic/callback в поле разрешённых URL обратного вызова?

Да, можно попробовать.

Можете ли вы предоставить больше деталей о том, как реализована ссылка «Получить помощь на форуме сообщества»? Куда ведёт эта ссылка? Я сейчас исхожу из того, что кнопка обрабатывается через Auth0, и что добавление новой конфигурации URL приведёт к тому, что кнопка будет правильно вести на /auth/oauth2_basic для запуска процесса входа.

Извините за медленный ответ — только вернулся после рождественских каникул!

Я сделал следующее:

но получил тот же результат.

Эта ссылка ведёт на https://dev-zb38hsho.us.auth0.com/samlp/5GpVvVgryMnBaNJFuLt5DW3bs89jO0hr, где dev-zb38hsho — это идентификатор нашего экземпляра Auth0, а 5GpVvVgryMnBaNJFuLt5DW3bs89jO0hr — идентификатор клиента для приложения Discourse в Auth0.

Переход по этой ссылке перенаправляет на https://dev-zb38hsho.us.auth0.com/u/login?state=SESSION_SPECIFIC_TOKEN.

Ключевой момент заключается в том, что Discourse должен инициировать процесс аутентификации по адресу /auth/oauth2_basic, затем перенаправлять в Auth0, а после возвращаться на /auth/oauth2_basic/callback.

Я надеялся, что мы сможем настроить Auth0 так, чтобы вход в систему запускался с первого URL-адреса, но, судя по всему, он сразу перенаправляет Discourse на URL-адрес обратного вызова.

Не могли бы вы обновить кнопку так, чтобы она вела на /auth/oauth2_basic на форуме? Это запустит процесс аутентификации и сразу перенаправит в Auth0, поэтому общий пользовательский опыт останется прежним.

Да, это работает! Он действительно приостанавливает процесс на странице-интерстициале с кнопкой «Продолжить». Обязательно ли взаимодействие пользователя для безопасного запуска OAuth-потока или чего-то подобного?

Если бы существовал способ сделать это

то это было бы отличным бонусом, но в целом это замечательно! Спасибо :folded_hands:

Эта страница отображается, когда на сайте используется несколько способов входа. Если вы отключите «локальный вход» (имя пользователя/пароль), то процесс входа будет происходить напрямую.