分享 Discourse 单点登录

rina · 2015年10月28日 · 最后由 linlinlin 回复于 2022年03月30日 · 3710 次阅读

PS: 楼主是个新手,写错的地方还请指正 :)

背景

公司内部有个discourse论谈:http://stage.bbs.uboss.me/, 想将这个论坛上注册功能屏蔽掉,注册登录功能统一到 Rails 项目:http://stage.uboss.me/ 这个网站上登录,帐户也是http://stage.uboss.me/这个网站上的帐户信息。

过程

discourse本身#设置/登录#里有支持 sso 单点登录配置。具体文档信息可以看 这里.

参数解析

这里解释一下这几个配置字段的含义:

sso_url: 这个参数的作用是当你点击 discourse 论坛的登录时,要跳转的路径,这里要求统一到http://stage.uboss.me/这里登录,所以地址自然指向这个路径,但是要指出具体指向哪个 action, 因为在这个 action 里要校验传入的 secret 和配置的 secret 是否一致。

sso_secret : 这个 secret 是一个字符串,可以随意填写,但是必须和 action 里校验的一致。

enable_sso : 开启 sso 登录模式。如果误启动了可能进行 discourse 项目,执行:rails c后,设置:SiteSetting.enable_sso = false就可以关闭了。

添加一个 Action

创建一个文件:app/controllers/discourse_sso_controller.rb

这里面要处理两件事:

1. 判断用户是否登录,是:校验密码是否一致。

2. 判断用户是否登录,否:跳转到登录页面

参考代码:

class DiscourseSsoController < ApplicationController

  def sso  
   if current_user
      secret = ENV['SECRET']
      sso = SingleSignOn.parse(request.query_string, secret)
      sso.email = current_user.email
      sso.external_id = ENV['KEY'] # unique to your application
      sso.sso_secret = secret
      redirect_to sso.to_url(ENV['CALLBACK_URL'])
    else
      redirect_to(new_user_session_url(redirect: 'discourse'))
    end
  end

end

这里如果用户没用登录,则跳转到登录页面。登录完成后需要跳转回 discourse 论坛 (此时论坛是登录状态), 所以在请求时将请求地址记录下来方便登录后跳转。

app/controllers/application_controller.rb中添加

内容如下:

before_action :store_discourse_sso_location

def store_discourse_sso_location
  if request.xhr? or ! request.get?
    return
  end
  if( request.path == discourse_sso_path )
    session[:discourse_sso] = request.fullpath if current_user.blank?
  end
end

SessionsController判断一下,然后跳转到 session[:discourse_sso] 这个路径。

这里面用到的几个参数解释一下:

配置以下信息secret要与 discourse 上的 secret 一致,key 取一个唯一值,callback_url认证后跳转路径:http://discourse_url/session/sso_login\

SECRET: xxx KEY:123 CALLBACK_URL: http://stage.bbs.uboss.me/session/sso_login

考虑到密码的安全性,使用了 gem figaro, 配置使用文件可以 google 之。

配置路由

在 config/routes.rb 添加一条路由:get '/discourse/sso', to: 'discourse_sso#sso'

这个 url 配置是在 discourse 上配置 sso_url 用到的。

添加 discourse 中的 single_sign_on 文件

放于 lib/single_sign_on.rb

做好了这些之后就可以开始测试了。

此文来自 Rina's Blog

你好,完想问一下 discourse 的 external_id 是需要自己来设置的吗,我拼接完 payload 后一直登陆失败

需要 登录 后方可回复, 如果你还没有账号请 注册新账号