Авто-вход с плагином OpenId Connect и AWS Cognito

Привет. Я новичок в Discourse. У меня есть приложение, работающее на AWS, которое использует Cognito для аутентификации. Я хочу связать это приложение с новым форумом на хостинге Discourse. У меня уже есть хорошие начальные шаги, но я надеюсь, что кто-то сможет дать рекомендации по завершающим этапам настройки.

Цель — сделать процесс входа бесшовным между моим приложением и форумом Discourse. То есть:

  • Если пользователь вошёл в моё приложение, то при переходе на форум Discourse распознаёт это и не требует повторного входа.

  • Аналогично, если пользователь сначала заходит на форум Discourse и не авторизован, Discourse должен перенаправить его на страницу входа моего приложения (или на размещённый интерфейс входа, если это необходимо).

Плагин OpenId Connect Authentication Plugin кажется идеально подходящим для этой задачи. Я оформил бизнес-план в Discourse, чтобы гарантировать возможность использования этого плагина.

Я прошёл инструкции, предоставленные @david, и выполнил то, что считаю правильной настройкой на стороне Cognito:

  1. Из Cognito я получил «документ обнаружения OpenID Connect» и «client ID OpenID Connect».

  2. В настройках Discourse в разделе openId_Connect я добавил эти данные и сохранил их.

  3. Я включил «аутентификацию через OpenID Connect» и в поле «openid connect authorize scope» указал «openid email». Эти настройки также сохранены.

Согласно описанию плагина, этого должно быть достаточно, верно?

Однако, когда я вхожу в своё приложение, а затем перехожу на форум, ничего не происходит. Отображается обычная главная страница с кнопками «Зарегистрироваться» и «Войти». Я надеялся, что после проверки с Cognito меня автоматически авторизует, но этого не происходит. Что ещё нужно сделать?

Кроме того, если пользователь приходит на сайт форума впервые (никогда не входивший в моё приложение), он не должен видеть кнопки регистрации и входа в Discourse — вместо этого он должен видеть кнопку, нажатие на которую перенаправит его на страницу входа моего приложения. Как это добавить?

И наконец, пользователи подписываются на моё приложение и платят за использование премиум-функций. Эта информация сохраняется как пользовательские атрибуты в Cognito (существует пользовательский атрибут, указывающий, подписан пользователь или нет). Только подписанные пользователи должны иметь возможность публиковать сообщения на форуме. Таким образом, когда Discourse запрашивает информацию о пользователе у Cognito, он должен проверять пользовательский атрибут и разрешать публикацию только в случае активной подписки. Как это реализовать?

Будучи новичком в Discourse, я был бы очень благодарен за любую информацию по этим вопросам. Спасибо!

Привет @JQ331 :wave:

Автоматический вход поддерживается только если ваш сайт является приватным (включена настройка сайта login_required).

Так и должно работать по умолчанию. Убедитесь, что вы отключили все другие методы входа, включая «локальные входы».

К сожалению, это невозможно с помощью плагина OIDC.

@david, большое спасибо за ваш ответ. Это очень полезно.

Где находится эта настройка сайта «login_required»? Под словом «приватный» вы имеете в виду, что пользователи могут просматривать содержимое сайта только после входа в систему? Очевидно, это не то, что мне нужно. Я хочу, чтобы вход в систему требовался только для публикации, а единственным способом входа было использование моего отдельного приложения.

Я предполагаю, что вы имеете в виду раздел настройки —> вход> включить локальные входы (снять эту галочку). Я снял все галочки, касающиеся локальных входов. Но что мне следует выбрать здесь? Например, если я использую плагин для связки моего отдельного приложения для входа, является ли это отдельное приложение «SSO» или «OAuth2»? (Задаюсь вопросом, например, нужно ли мне выбрать «SSO переопределяет email» или «OAuth2 переопределяет email»?

Касательно возможности публикации только для платных пользователей:

Это фундаментальное требование, поэтому, возможно, мне придется проявить изобретательность. Есть ли другой вариант, кроме плагина SSO? Если нет, я все еще вижу возможность реализации, если выполнено одно из следующих условий:

  1. В Discourse есть разные уровни прав пользователей. То есть я мог бы настроить так, чтобы пользователь мог быть авторизован, но не иметь права публиковать сообщения или отвечать на них. В этом случае мне нужно было бы устанавливать уровень прав пользователя на основе информации, которую Discourse получает от Cognito (подписан или нет).

  2. Если это не сработает, есть ли в Discourse рабочий плагин для Stripe, который позволяет пользователям быть авторизованными, но публиковать сообщения только в том случае, если они оплатили подписку через систему Stripe?

  3. Если ни один из этих вариантов не сработает — например, если в Discourse НЕТ возможности различать уровни привилегий пользователей, которые я могу установить, — тогда, похоже, мне придется сделать так, чтобы пользователь либо был авторизован, либо нет, и публиковать могли только авторизованные пользователи. Правильно ли я понимаю?

Если это так, то мне придется самостоятельно разобраться на стороне моего приложения, как сообщать Discourse, что пользователя следует авторизовывать только в том случае, если он оплатил подписку в моем приложении.

Спасибо.

В таком случае автоматический вход в систему в настоящее время не поддерживается. Пользователям нужно будет нажать кнопку входа.

Хорошо, теперь кнопка входа должна вести напрямую к вашему провайдеру идентификации. Это работает?

Да, вы можете настроить все категории так, чтобы их мог читать «каждый». Но создавать темы или отвечать на них смогут только пользователи определённой группы. Если вы хотите автоматизировать этот процесс, вы можете использовать API для добавления или удаления людей из группы.

Круто — похоже, я почти у цели. Просто хочу уточнить:

Мне нужно следующее:

  1. Все могут читать контент сайта (независимо от того, авторизованы они или нет).
  2. Публиковать могут только авторизованные пользователи.
  3. Если вы авторизованы в моём приложении и переходите на Discourse, то система связывается с Cognito и автоматически выполняет вход, позволяя вам публиковать сообщения.

Вы говорите, что пункт (3) невозможен? Вы имеете в виду, что автоматический вход работает только в том случае, если контент сайта скрыт от публичного доступа?


Похоже, это именно то, что мне нужно. Судя по вашему совету «использовать API», вы имеете в виду что-то вроде:

  1. Пользователь пытается войти на мой форум.
  2. Его перенаправляют на вход в моё приложение.
  3. После входа в моё приложение оно проверяет, оплачена ли подписка пользователя. Если да, то приложение делает запрос к API Discourse, чтобы добавить этого человека в «группу», имеющую право создавать темы и отвечать.

Именно это вы имели в виду? Если да, есть ли какое-то основное руководство по тому, как добавлять людей в группы через API?

Спасибо, это действительно помогает мне продвинуться вперёд.

Кажется, у нас разные определения термина «автоматический вход».

Discourse может подключаться к провайдеру OIDC для входа. Этот процесс запускается, когда пользователь нажимает кнопку «Войти» на форуме. Это всегда работает, независимо от конфигурации.

Если сайт требует входа (т. е. включена настройка «Требуется вход»), то пользователь сразу перенаправляется на экран входа OIDC, без необходимости нажимать кнопку.

Да, именно это я и имел в виду. Вот документация по этой конечной точке API.

Круто. Спасибо! Я изучу документацию по этому API. Звучит очень перспективно.

Насчет «авто-входа» — кажется, вы имеете в виду «авто-вход = автоматическое перенаправление пользователя на экран входа». То есть, судя по вашему описанию, когда пользователь заходит на мой форум Discourse, есть два варианта:
Вариант 1. Сайт «автоматически» перенаправляет его на отдельную страницу входа в приложение. Это происходит независимо от того, вошел ли пользователь уже в мое приложение или нет. (Это то, что вы называете «авто-входом», и вы говорите, что это происходит, если установлен параметр «login_required».)

Вариант 2. Сайт не выполняет никакого автоматического перенаправления. Вместо этого на странице есть обычная кнопка входа. Если пользователь нажимает на эту кнопку или пытается опубликовать сообщение, форум перенаправит его на страницу входа в мое приложение.

Я надеялся на Вариант 3: если пользователь уже вошел в мое приложение, то при переходе на мой форум Discourse этот форум проверяет в Cognito, авторизован ли пользователь. Если пользователь авторизован в Cognito, то Discourse автоматически вводит его в форум без необходимости повторного отдельного входа.

Я новичок в технологиях OpenID, но точно считал, что это возможно, потому что если пользователю приходится отдельно входить и в приложение, и в форум при переключении между ними, это не обеспечивает бесшовного опыта.

Разве нет способа, чтобы форум Discourse проверял статус авторизации в Cognito и обновлял вход пользователя, не заставляя его проходить отдельный процесс входа?

Кстати, я предполагаю, что прямая интеграция Discourse в мое приложение не поможет. Я бы сделал это, если бы мог, но, похоже, это возможно только через iframe, что не решает проблему аутентификации.

Технически это возможно в спецификации OIDC, но, к сожалению, Discourse на данный момент это не поддерживает.

Хм. Я слышал, что есть два способа связать Discourse с отдельным провайдером аутентификации, например Cognito: плагин OpenId или использование Single Sign On для Discourse.

Я совершенно не знаком с процессом Single Sign On, но может ли это быть способом сделать то, что я хочу — избежать двойного входа пользователей?

Или, может быть, просто при входе в мое приложение отправлять API-запрос в Discourse и таким образом авторизовывать пользователя?

(В документации, на которую я дал ссылку, также говорится об указании членства в группах — я предполагаю, что это позволит решить мою задачу: разрешить публикацию только в группе, куда входят только ПЛАТЯЩИЕ пользователи).