Интеграция в кастомную систему аутентификации, где email-адреса не уникальны?

Мы хотели бы интегрировать Discourse в наши существующие системы, чтобы перестать полагаться на наш сервер Discord для поддержки. У нас уже настроена собственная система учётных записей, и мы хотели бы, по возможности, использовать её повторно, чтобы снизить трение. Однако в нашем случае уникальность адресов электронной почты не требуется, уникальными должны быть только имена пользователей. Похоже, что Discourse исходит из предположения, что адреса электронной почты будут глобально уникальными, что мешает нам выполнить прямую интеграцию.

Я ознакомился с DiscourseConnect, который казался многообещающим, но в нём указано:

Discourse использует адреса электронной почты для сопоставления внешних пользователей с пользователями Discourse

Это не сработало бы в нашем случае, так как несколько учётных записей могут (и делают) использовать один и тот же адрес электронной почты.

Затем мы изучили Discourse OAuth2 Basic, который на первый взгляд не требовал адреса электронной почты:

Единственным обязательным атрибутом является id

Однако позже там всё же упоминается необходимость ручного ввода адреса электронной почты, если он не предоставлен источником OAuth:

Обратите внимание, я пропустил путь к электронной почте: SoundCloud не предоставляет адрес электронной почты, поэтому пользователю придётся ввести и подтвердить его при первой регистрации на Discourse

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

Вариантов немного. Адреса электронной почты должны быть уникальными.

Можно прибегнуть к хитрости, например, переписывать адреса следующим образом:

myaddress@gmail.com -> myaddrerss+username@gmail.com

Это сработает для сервисов, поддерживающих адреса с символом «+», а таких большинство.

Мы рассматривали это, но не были уверены, как это повлияет на поток OAuth или добавит ли это трение при регистрации/входе. Такие изменения были бы незаметны для пользователя, поэтому они не смогли бы войти в систему, если не введут этот изменённый адрес электронной почты. Наш текущий сервер учётных записей также не будет знать об этих изменениях, поэтому даже если они введут изменённый адрес, мы не сможем найти его в наших записях?

Это также нарушит работу пользователей, которые уже используют алиасы электронной почты, не так ли?

Действительно, хорошего решения нет.

Если только они не войдут, используя имя пользователя.

Если бы вы разрешили вход по электронной почте (что, как мне кажется, невозможно с DiscourseConnect), всё бы работало как надо, если бы им отправлялась ссылка на почту.

Вам нужно будет обеспечить его осведомлённость. Думаю, это будет первым шагом.

Другой неуклюжий вариант — разрешить вход в Discourse только «первому» пользователю (как бы ни определялось это понятие).

Ещё одно неуклюжее решение — заставить пользователей вашей системы получать уникальные адреса для каждой учётной записи.

… Только при условии, что их почтовый сервер поддерживает адресацию с плюсом; это не гарантировано.

Да, конечно. Именно так и должно быть, и это то, к чему я стремлюсь. Я искал решение, которое полностью запрещает вход по электронной почте, оставляя вход по имени пользователя единственным методом. Я готов полностью отказаться от поддержки электронной почты (например, от уведомлений на email), просто выдавая поддельные адреса от OAuth-сервера. Однако это создаст неудобства, если возможность входа по электронной почте всё ещё будет доступна, так как пользователи будут пытаться это сделать и терпеть неудачу.

Это фактически заставило бы нас отслеживать два разных адреса электронной почты на каждого пользователя, что тоже нежелательно. Кроме того, как отметил @supermathie, это не гарантирует работу со всеми провайдерами, и всё равно создаёт неудобства, поскольку нам теперь придётся сообщать пользователям о специальном адресе электронной почты этого форума, который им нужно запомнить.

Да, технически это сработает. Но по очевидным причинам это не будет реальным решением, так как это заблокирует вход всем остальным, кто захочет присоединиться к форуму.

Технически мы не можем этого сделать. Самая очевидная причина в том, что у нас уже есть пользователи, у которых адрес электронной почты совпадает с другими учётными записями. Но главная причина в том, что мы просто не можем этого сделать. Проект, в который мы планируем внедрить Discourse, — это Pretendo Network, проект эмуляции серверов для Nintendo Network. Nintendo разрешала повторное использование адресов электронной почты в своей системе учётных записей, поэтому для точной эмуляции серверов мы тоже должны это делать. Требование уникальных адресов электронной почты для нас невозможно.

Один из членов моей команды предложил запустить наш собственный SMTP-сервер, который будет сопоставлять поддельные адреса электронной почты для Discourse с реальными адресами наших пользователей, пересылая отправленные из Discourse письма таким образом. Это сработает, но, очевидно, потребует от нас более высоких технических затрат и всё равно не решит проблему отключения входа по электронной почте и упомянутых неудобств в нашем случае.

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

Я говорю по памяти, но вы можете использовать DiscourseConnect с поддельными, но уникальными адресами электронной почты. Если на вашей стороне гарантируется уникальность имен пользователей, реализация может быть довольно простой. Адрес электронной почты можно установить, например, как username@invalid.com.

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

Недостаток этого подхода заключается в том, что вам потребуется отключить отправку писем в Discourse. Это можно сделать, установив параметр disable emails в значение yes или non-staff (если у ваших сотрудников уникальные адреса электронной почты).

Также можно рассмотреть использование адресов с символом «+» для пользователей с дублирующимися адресами электронной почты. В последний раз, когда я проверял, Discourse считал адреса с символом «+» уникальными. Просто убедитесь, что вы кодируете адреса URL перед их использованием в полезной нагрузке DiscourseConnect. Риск здесь заключается в том, что если у пользователей есть дублирующиеся адреса электронной почты и они используют почтовый сервер, который не поддерживает адреса с символом «+», они не получат письма от Discourse, но это позволит другим вашим пользователям получать письма от Discourse.

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

Еще один случай, когда я сталкивался с проблемой сопоставления адресов электронной почты, — это когда из-за ошибок в коде на стороне провайдера аутентификации записи SSO на сайте Discourse были повреждены. В этом случае сайт смог удалить все записи SSO на стороне Discourse, после чего Discourse снова связал пользователей с адресом электронной почты из полезной нагрузки SSO при их следующем входе. Затем Discourse сгенерировал новые записи SSO для пользователей. Это все еще будет работать с поддельными адресами электронной почты.

Логика аутентификации через DiscourseConnect заключается в том, что Discourse сначала пытается найти пользователя по полю external_id в полезной нагрузке. Если пользователь не найден, система пытается найти его по полю email. Если и в этом случае пользователь не найден, выбрасывается ошибка.

Перед внедрением этого решения на работающем сайте обязательно перепроверьте всё, но я знаю, что подход с поддельными адресами электронной почты использовался на производственных сайтах в случаях, когда реальные адреса электронной почты пользователей не могли быть переданы сайту Discourse.

@simon Спасибо за информацию! Всё больше похоже на то, что мы движемся в правильном направлении.

Это приемлемо, и я уже упоминал ранее, что это допустимое решение проблемы «все адреса электронной почты должны быть уникальными». Я совершенно не против фактически отключить электронную почту в нашем случае, и использование поддельных адресов — это решение, к которому я пришёл ещё до создания этого сообщения.

Возможно, я изначально выразился неясно, но суть моего поста заключалась в том, чтобы узнать, возможно ли заставить окно входа принимать только имена пользователей, поскольку сейчас вход возможен как по имени пользователя, так и по адресу электронной почты. Если в окне входа на Discourse всё ещё отображается возможность входа по электронной почте, наши пользователи могут попытаться использовать свой существующий адрес электронной почты и столкнуться с ошибкой. Таким образом, нам либо придётся смириться с тем, что люди будут пытаться и терпеть неудачу, используя свои текущие адреса, либо как-то уведомить пользователя о его новом, специфичном для форума адресе. Оба варианта могут вызвать путаницу и усложнить взаимодействие с пользователем, поэтому в идеале мы хотели бы просто ограничить окно входа принятием только имён пользователей.

К сожалению, уникальность адресов электронной почты у сотрудников тоже не гарантирована, поэтому я не хотел бы на это полагаться. Этот параметр отключает только отправку писем? Или он отключает использование электронной почты в целом, как раз то, что мне нужно для окна входа?

Я несколько раз просмотрел страницу DiscourseConnect и не нашёл там этой опции. Возможно, есть лучшее место для просмотра подобной документации? В том сообщении я не увидел ссылок на полную документацию, поэтому предположил, что вся информация там исчерпывающая.

Признаюсь, я сам не настраивал DiscourseConnect, чтобы изучить настройки. Я надеялся, что документации будет достаточно, чтобы понять, что можно и чего нельзя сделать, чтобы нам не пришлось разворачивать целую тестовую копию форума, если мы ещё не решили окончательно внедрить его. Но, похоже, какая-то информация всё ещё недоступна, если только я не упустил что-то очевидное?

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

Похоже, я действительно неправильно понял это, так как в самом сообщении это не очень ясно. Однако моя цель при упоминании этого заключалась в том, чтобы показать зависимость от уникальности адресов электронной почты, что всё ещё остаётся проблемой.

Это определённо было неясно исходя только из сообщения, если только я что-то не упустил. Спасибо за разъяснение! Это звучит гораздо ближе к тому, на что я надеялся.

Изменили ли вы текст, указывающий, что использование электронной почты допустимо? Все строки текста можно переопределить.

Это был бы хороший кандидат для документации, если мы ещё этого не сделали.

Если вы хотите легко протестировать эти сценарии с помощью тестового сайта, вы можете использовать, например, bratwurst.

Насколько мне известно, заставить окно входа в Discourse отображать только поле имени пользователя невозможно. Кроме того, вам пришлось бы решать проблему регистрации пользователей. Именно поэтому я предлагаю использовать DiscourseConnect.

При включении DiscourseConnect он становится единственной системой аутентификации для вашего сайта на Discourse. Когда пользователи нажимают кнопку «Войти» на Discourse, их автоматически перенаправляет на URL, указанный в настройке сайта discourse_connect_url. Дальнейшую обработку берет на себя ваша система аутентификации. Это означает, что если у вас есть сайт, где пользователи сейчас входят, используя имя пользователя и пароль, они будут продолжать входить таким же образом.

Для настройки этого требуется возможность добавить некоторый код в бэкенд сайта, на который пользователи входят сейчас. Настройка не слишком сложна. Хороший пример кода можно найти здесь: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub. Кроме того, вы можете получить помощь по этому вопросу на данном форуме.

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

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

Мое непонимание DiscourseConnect, по-видимому, было корнем этой проблемы и всей путаницы.

Если вас не беспокоит, что Discourse будет отправлять уведомления на email, вы можете настроить ваш SSO так, чтобы он передавал Discourse адрес вида game-username@bogus.invalid.

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

Приношу свои извинения, я не увидел ваш ответ прошлой ночью.

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

Честно говоря, найти реальную документацию по любым вопросам, кроме API, кажется довольно сложным. По крайней мере, с точки зрения первого пользователя.

На главной странице Discourse нет ничего очевидного, что ссылались бы на какую-либо документацию, а все ссылки на странице DiscourseConnect ведут либо на нерелевантные страницы, либо обратно на сам пост. Поиск «документация Discourse» в поисковых системах приводит к таким страницам, как Documentation - Discourse Meta, что является просто категорией форума, а не реальной страницей документации, и https://docs.discourse.org/, но это документация по API, и, похоже, там нет ничего о функциях, таких как DiscourseConnect.

Попытка найти эту информацию естественным путем оказалась сложной.

Есть ли какое-то очевидное место, которое я просто пропустил, где всё это подробно разбирается? Похоже, что самое близкое, что я могу найти, — это категория форума, так как там много руководств и инструкций, написанных сотрудниками и другими пользователями по различным темам. Но использовать форум для документирования самого себя мне казалось неправильным. Разве нет отдельного источника документации для функций и инструментов Discourse, как это есть для API Discourse?

Верно, это сработает. Как уже не раз упоминалось, использование поддельного адреса электронной почты от провайдера OAuth было предложено нами ещё до создания этого поста.

Однако само по себе это не решает проблему: «если пользователь увидит в форме входа, что принимаются адреса электронной почты, он попытается использовать их, но потерпит неудачу из-за наличия поддельного адреса».

Тем не менее, я только что понял, что неправильно представлял себе работу DiscourseConnect. Я думал, что форма входа всё ещё находится на сайте Discourse, а Discourse просто обращается к провайдеру OAuth. @simon теперь исправил это для меня: я не знал, что процесс физически перенаправляет пользователя на нашу собственную форму входа. Это само по себе решает практически все мои вопросы. Спасибо, кстати!

Даже если вы просто хотите протестировать систему и не планируете продолжать использовать наш хостинг, пожалуйста, не стесняйтесь создать пробный сайт! Нам это не помешает!

Спасибо за этот отзыв — мы сознательно прилагаем усилия, чтобы улучшить ситуацию.

Не возражаете ли вы, если мы свяжемся с вами для дальнейшего обсуждения?

Ни один из людей, с которыми я работал, не был недоволен хостингом discourse.org. Если по какой-то причине вам нужно самостоятельно разместить свой проект, вы можете войти в систему по адресу https://dashboard.literatecomputing.com/, присоединиться к группе «free trial» (бесплатная пробная версия) и бесплатно пользоваться панелью управления (если вы не сможете разобраться, как присоединиться к группе бесплатной пробной версии, скорее всего, вам потребуется больше поддержки, чем я готов предоставить). Если вы готовы использовать Digital Ocean и Mailgun, вам нужно только ввести ключи API и имя хоста.

Мне неловко, но я даже не подумал об этом варианте! Это хороший момент, и мы, скорее всего, воспользуемся пробным периодом для тестирования.

Ранее сегодня я уже изучал ваши варианты хостинга, так как это было бы проще, чем самостоятельное размещение, но, к сожалению, это в основном выходит за рамки нашего бюджета. У нас более 200 000 пользователей, поэтому тариф «Basic» нам не подходит. У нас более 5 сотрудников, поэтому тариф «Standard» тоже не вариант. И поскольку мы являемся проектом с открытым исходным кодом (FOSS), мы работаем на пожертвования и едва сводим концы с концами, чтобы оплачивать одного штатного разработчика, поэтому тариф «Business» для нас совершенно недоступен.

Тем не менее, идея использовать пробный период для тестирования — фантастическая, спасибо! В любом случае мы уже самостоятельно размещаем большинство наших сервисов, включая наш экземпляр Mastodon, поэтому самостоятельное размещение Discourse не станет для нас большой преградой.

Конечно! Всегда рад помочь, чем смогу, даже если это просто предоставление обратной связи. Надеюсь, моё сообщение не показалось слишком негативным, поскольку это не было моей целью, хочу это сразу прояснить.

Если вам интересно, мы предлагаем бесплатный хостинг для некоторых проектов FOSS… количество ваших сотрудников превышает наши лимиты, но лица, принимающие решения, возможно, смогут закрыть на это глаза.

(обратите внимание, что наше определение «сотрудников» здесь — это «Администраторы» + «Модераторы по всему сайту», а не «сотрудники соответствующей компании» — мне было бы интересно узнать, какое определение «сотрудников» было у вас в голове до этого)

Нет, это было вежливо и разумно :+1:t3:

Спасибо! Я пропустил это на вашей странице с тарифами. Я только что вернулся, чтобы перепроверить, и оно спрятано глубоко внизу страницы :sweat_smile: Я изучу это и поговорю с моими коллегами!

В нашем случае определение «сотрудников» охватывает две основные роли:

  • Люди из нашей основной команды разработки (как проект с открытым исходным кодом, это может колебаться, так как люди могут приходить и уходить, но у нас всегда было около 5–10 активных разработчиков в любой момент времени)
  • Наша команда модерации (не-разработчики и участники сообщества, которые модерируют наши сервисы, такие как онлайн-матчи и наша реализация Miiverse, а также наш сервер Discord). Это также варьируется

Мы МОГЛИ бы ограничить это только 5 нашими разработчиками, что укладывается в эти лимиты, но это потребовало бы от нас решить, кто получает полные права на форуме, а кто нет. Это также ограничило бы количество людей, способных модерировать форумы (мы ввели команду модерации вне команды разработчиков именно для того, чтобы снять эту нагрузку с нас)

Я обязательно подниму этот вопрос с людьми на моей стороне и посмотрим, как всё сложится!

Мне кажется, что TL4/модераторы категорий могли бы здесь очень помочь.