Объединение Discourse SSO с существующим сайтом Rails с Devise
У меня есть приложение rails, которое использует devise для аутентификации пользователей. Я добавил дискуссионный форум, и все прошло гладко, и он находится на поддомене. Я прочитал пост на https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045 но до сих пор не знаю, что делать с разработкой, когда пользователь входит в систему. на существующем сайте рельсов. В настоящее время это процесс, как я понимаю:
Шаг 1: Пользователь посещает форум Дискурс на поддомене. Пользователь должен войти в систему, поэтому нажимает кнопку входа.
Шаг 2: Пользователь отправляется на страницу входа на существующем сайте rails.
Шаг 3: Пользователь входит в систему на сайте rails.
Шаг 4: Пользователь должен быть перенаправлен на дискурс субдомена форума, вошедшего в систему.
У меня вопрос: что мне нужно сделать, чтобы при входе пользователя на шаге 3 он был перенаправлен обратно на поддомен? Кто-нибудь успешно это реализовал? Я видел этот фрагмент кода на этой странице прохождения:
class DiscourseSsoController < ApplicationController
def sso
secret = "MY_SECRET_STRING"
sso = SingleSignOn.parse(request.query_string, secret)
sso.email = "user@email.com"
sso.name = "Bill Hicks"
sso.username = "bill@hicks.com"
sso.external_id = "123" # unique to your application
sso.sso_secret = secret
redirect_to sso.to_url("http://l.discourse/session/sso_login")
end
end
Это то, что мне нужно добавить в мое существующее приложение rails? Я предполагаю, что синтаксический анализ проверяет, есть ли эта информация в URL, и если да, то он перенаправляет, как только он завершает процесс входа в систему devise, и если нет, он просто функционирует как обычно. Разместил бы я этот код где-нибудь в файлах устройства?
2 ответа
This is pretty straightforward. Following on from the instructions at https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045 and extrapolating a little, I have this working:
1) Put the reference implementation - https://github.com/discourse/discourse/blob/master/lib/single_sign_on.rb - in your #{Rails.root}/lib directory
2) Add this route to routes.rb
get 'discourse/sso' => 'discourse_sso#sso'
3) Put this controller in your app/controllers directory
require 'single_sign_on'
class DiscourseSsoController < ApplicationController
before_action :authenticate_user! # ensures user must login
def sso
secret = "MY_SECRET_STRING"
sso = SingleSignOn.parse(request.query_string, secret)
sso.email = current_user.email # from devise
sso.name = current_user.full_name # this is a custom method on the User class
sso.username = current_user.email # from devise
sso.external_id = current_user.id # from devise
sso.sso_secret = secret
redirect_to sso.to_url("http://your_discource_server/session/sso_login")
end
end
4) Set up the SSO config in discourse to have the following
sso url: http://your_rails_server/discourse/sso
sso secret : what you set as MY_SECRET_STRING above
5) Disable other login types in discourse.
6) Try to login in discourse. It should work...
спасибо @DanSingerman
Они обновились с тех пор, как вы опубликовали ответ.
- Контроллер сейчас
class DiscourseSsoController < ApplicationController
def sso
secret = "MY_SECRET_STRING"
sso = DiscourseApi::SingleSignOn.parse(request.query_string, secret)
sso.email = "user@email.com"
sso.name = "Bill Hicks"
sso.username = "bill@hicks.com"
sso.external_id = "123" # unique id for each user of your application
sso.sso_secret = secret
redirect_to sso.to_url("http://l.discourse/session/sso_login")
end
end
Установите
Discourse API
gem или скопируйте класс SingleSignOn в папку lib. Этот класс находится в репозитории gem: https://github.com/discourse/discourse_api/blob/main/lib/discourse_api/single_sign_on.rb .О
query_string
: если вы тестируете локально, вы должны имитировать запрос, исходящий от Discourse, поскольку он будет содержать запрос с двумя параметрами, полезной нагрузкой и сигналом:https://somesite.com/sso?sso=PAYLOAD&sig=SIG