Объединение 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

Они обновились с тех пор, как вы опубликовали ответ.

  1. Контроллер сейчас
          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
  1. УстановитеDiscourse APIgem или скопируйте класс SingleSignOn в папку lib. Этот класс находится в репозитории gem: https://github.com/discourse/discourse_api/blob/main/lib/discourse_api/single_sign_on.rb .

  2. Оquery_string: если вы тестируете локально, вы должны имитировать запрос, исходящий от Discourse, поскольку он будет содержать запрос с двумя параметрами, полезной нагрузкой и сигналом:

    https://somesite.com/sso?sso=PAYLOAD&sig=SIG

Другие вопросы по тегам