ruby-on-rails 使用Devise将Discourse SSO与现有Rails站点合并

yvfmudvl  于 2022-12-05  发布在  Ruby
关注(0)|答案(2)|浏览(113)

我有一个现有的rails应用程序,它使用device作为它的用户身份验证。我添加了一个discourse forum,一切都很顺利,它驻留在一个子域上。我已经阅读了https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045上的帖子,但仍然不知道一旦用户登录到现有的rails站点,该如何处理device方面的事情。目前,这是我所理解的过程:
第一步:用户点击讨论论坛的子域,用户需要登录,点击登录按钮。
第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中,如果是,它会在完成devices登录过程后重定向,如果不是,它就照常工作。我会把这段代码放在devices文件中的某个地方吗?

k10s72fa

k10s72fa1#

这是非常简单的。根据https://meta.discourse.org/t/official-single-sign-on-for-discourse/13045中的说明并进行一些推断,我得到了如下结果:
1)将参考实现-https://github.com/discourse/discourse/blob/master/lib/single_sign_on.rb-放在#{Rails.root}/lib目录中
2)将此路由添加到routes.rb

get 'discourse/sso' => 'discourse_sso#sso'

3)将此控制器放入app/controllers目录

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)在讨论中设置SSO配置,使其具有以下内容

sso url: http://your_rails_server/discourse/sso
sso secret : what you set as MY_SECRET_STRING above

5)禁用会话中的其他登录类型。
6)试着用对话登录。应该能用...

os8fio9y

os8fio9y2#

谢谢@丹辛格曼
自从您发布答案后,它们已更新。
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 API gem或将SingleSignOn类复制到lib文件夹中。此类位于gem存储库中:https://github.com/discourse/discourse_api/blob/main/lib/discourse_api/single_sign_on.rb
1.关于query_string:如果您在本地进行测试,您应该模拟来自Discourse的请求,因为它将包含一个带有两个参数的查询,即有效负载和sig:
https://somesite.com/sso?sso=PAYLOAD&sig=SIG

相关问题