У меня есть рабочий форум Discourse, где пользователи могут создать локальный вход (имя пользователя + пароль).
Я хочу использовать их логин и пароль в другом приложении. Иными словами: пользователи будут вводить имя пользователя и пароль в другом приложении, и это приложение должно иметь возможность проверить, является ли это корректным входом для форума.
Я изучил документацию по API Discourse. Возможно многое, включая установку имени пользователя и пароля для конкретного пользователя, но я не нашел конечной точки API для проверки существующего имени пользователя и пароля по списку пользователей форума.
Я предполагаю, что такая конечная точка API должна существовать, так как форум должен иметь возможность выполнять эту проверку для входа пользователя через веб-интерфейс.
Какая конечная точка API используется для проверки имени пользователя и пароля при входе на форум?
Более прямой способ — использовать DiscourseConnect как механизм для проверки пользователей или разместить его перед вашим приложением с помощью discourse-auth-proxy.
Это рекомендуемые методы аутентификации пользователей, которые позволяют не обрабатывать учётные данные для входа напрямую. Кроме того, вам не придётся заниматься деталями двухфакторной аутентификации (2FA).
На самом деле моё «другое приложение» — это десктопное приложение, а не веб-приложение. Я не думаю, что в таком случае discourse-auth-proxy сработает.
На странице DiscourseConnect одним из первых утверждений является следующее:
Многие сайты, желающие интегрироваться с сайтом Discourse, хотят сохранять всю регистрацию пользователей на отдельном сайте. В такой конфигурации все операции входа должны быть переданы на этот другой сайт.
Это ровно противоположно тому, что я хочу сделать: я хочу передать все операции входа в Discourse. Есть ли способ использовать DiscourseConnect для этого?
Сложность заключается в том, что между провайдером (Discourse) и потребителем (вашим приложением) существует общий секрет. Если вы распространяете своё приложение, пользователи получат доступ ко всем секретам в нём.
Размещение auth-proxy перед кастомным минимальным веб-сервисом, который выдаёт подписанный токен вашему приложению, может сработать хорошо.
Уверен, существуют и другие способы реализации этого, о которых я сейчас не думаю.
Вы имеете в виду API-ключ? Похоже, можно создать «избирательный» API-ключ, который имеет доступ только к определённым конечным точкам API. Всё ещё неясно, какие именно конечные точки потребуются, если я выберу этот подход. Вы знаете?
Да, минимальный веб-сервис с прокси-аутентификацией может стать хорошим решением; мне придётся немного поэкспериментировать, чтобы это выяснить.
Не совсем — речь идёт о значении discourse connect provider secrets для приложения, которое необходимо установить в сочетании с enable discourse connect provider.
Если я правильно понимаю, этот метод подразумевает вход пользователя через браузер. Это может сработать, хотя я надеялся найти способ, при котором имя пользователя и пароль вводятся непосредственно в нашем десктопном приложении без открытия браузера.
Я понимаю, что подход, который я имею в виду, не будет поддерживать двухфакторную аутентификацию (TFA), если я не реализую её самостоятельно, и не будет поддерживать вход через сторонних провайдеров (Google, Facebook, Discord и т.д.).
Насколько я понимаю на данный момент, похоже, что метод, используемый в примере с React Native, можно адаптировать для нашего десктопного приложения (которое написано на Python).
Используемая точка доступа к API — это <site>/session, и она требует имя пользователя, пароль и CSRF-токен. CSRF-токен можно получить по адресу <site>/session/csrf.
Это очень близко к тому, что я искал. Думаю, я попробую это сделать и сообщу, если у меня получится.
Документирована ли точка доступа к API <site>/session где-либо?
Лучший способ получить токен для вашего десктопного приложения — использовать ключи API пользователя.
Вам всё равно потребуется веб-интерфейс: либо встроенный в приложение, либо через открытие браузера. Однако, если вы зарегистрируете ваше приложение как обработчик протокола, используемого мобильными приложениями, вы сможете легко получать токен таким образом. В таком случае браузер потребуется снова только в случае истечения срока действия токена или если пользователь зайдёт с другого устройства.
По моему личному опыту, использование ключей API пользователя — гораздо более безопасный и простой вариант, чем попытки работать с эндпоинтами сессий.
Вот 20 строк кода на Python, которые выполняют примерно ту же задачу, что и код React Native, упомянутый @renato (за исключением совместимости с Discourse 2.5 — она мне не нужна)
Это работает хорошо, при условии, что вы используете базовый вход по имени пользователя и паролю. Я всё ещё изучу альтернативные методы, используя вход через SSO Discourse, настроенный в экземпляре Discourse.
Я попытался применить это, но у меня не получается заставить это работать. Ниже приведён некоторый (упрощённый) код на Python, который генерирует URL для .../session/sso_provider. При попытке его использовать я получаю ошибку Login Error. Не имею понятия, что это означает.
Как администратор, включите verbose discourse connect logging, попробуйте снова, а затем проверьте /logs на вашем форуме, чтобы увидеть более подробные сообщения об ошибках, например, https://forum.embeetle.com/logs.
Кстати, вам нужно немедленно отозвать и изменить этот секрет, так как любой, у кого он есть, может войти в ваше приложение, как я только что сделал во время тестирования.