思い付くまでタイトル未定

RubyとかRailsとかももクロちゃんとか色々な事書きます。

DiscourseとRailsアプリでSingle Sign On!

今回はDiscourseのSSOを使ってみたいと思います。
Discourse - About
英語あんまり読めないけど、SSOあるよって書いてあります。

用意するのは以下の3つ

  • インストール済みのDiscourse
  • Discourse以外のRailsアプリ(ログイン機能付き)
  • やる気

私が試したときは上記3つ以外に「若干の英語力」を用意しました。
google先生に尋ねてみるとわかります。

「日本語のページを検索」オプションを付けた結果がこちら。
f:id:kanahebiZ:20150526155842p:plain:w260
「このページを訳す」のリンクがあるのは日本語のページとは言わn(ry

という事で、早速試してみましょう!

Discourse側でやること

管理者で以下のURLにアクセスします。
http://"discourseのドメイン"/admin/site_settings/category/login

そしたら、以下の3つの設定をします。

  • enable sso にチェックを入れる
  • sso url に"Discourse以外のRailsアプリのドメイン"/discourse/ssoを入力する
  • sso secret に秘密の文字列を10文字以上で入力する

f:id:kanahebiZ:20150526163122p:plain:w260

以上!簡単です。

Railsアプリ側でやること

DiscourseSsoControllerを作成する
このcontrollerはdiscourseからユーザが飛ばされてくる時に使用します。
redirect_toで再度discourseに返しちゃうので、viewは必要ありません。

具体的な中身はこんな感じになります。

class DiscourseSsoController < ApplicationController
  def sso
    secret = "秘密の文字列"
    sso = SingleSignOn.parse(request.query_string, secret)
    sso.email = current_user.email
    sso.name = current_user.name
    sso.username = current_user.name
    sso.external_id = current_user.id
    sso.sso_secret = secret

    redirect_to sso.to_url("http://discourseのドメイン/session/sso_login")
  end
end

current_userの所は自分自身(ログイン中のユーザ)を取得しています。ここはどのようにログイン機能を実装しているかによって違うので、環境にあった設定をしてください。

次に、
routesの設定をする

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

こんな感じに書けば大丈夫です!

最後に、
SingleSignOnクラスを作成する
このクラスのソースはdiscourseディレクトリ配下のlib/single_sign_on.rbにもあります。
サーバーからもってくるの面倒くさいよっていう人はgithubにもあります。のでコピペしてください。

さて、以上でおしまいけるです。

実際に試してみよう!

discourseからログアウトするか、ログインしていないブラウザでdiscourseにアクセスします。
そして、ログイン!

できましたでしょうか。
Railsアプリ側でログインのセッションが切れていると勿論ダメなので、ログインしてから再度試してみてください。

悩んだところ

  • routesの設定してなくてroutingエラーになった。。。
  • lib/single_sign_on.rbを作ってなくてエラーになった。。。
  • sso.external_id の意味が分からなくてdiscourseのサンプルのまま"123"にしておいたら、どのユーザでログインしても皆最初にログインしたユーザになった。。。

また少し成長した気がします(笑)
おしまい。