Railsにてシングルサインオンを
実現する手法


ctokoro

                                2013/12/08   Hot startups beer bash tokyo #5
                                2014/02/19   Shibuya.rb[:20140219]

・背景

既存のアプリケーションの姉妹サイトとして
別アプリケーションを作る要件が出てきた。


ただし、

既存アプリケーションのユーザーでも
サインイン・サインアップしたい!!

(とりあえず)初期リリース


早くリリースして、
ユーザーを集めておきたい!


でも、既存ユーザーでも使えるように。。
とりあえず、DBを共有することに。

こういうアーキテクチャ



問題点


新規アプリケーション用のテーブルも既存DBに存在

Railsなので、スキーマ管理はmigration
新規アプリケーションのスキーマ変更も、
既存アプリケーションで管理

問題点


新規アプリケーション用のテーブルも既存DBに存在

Railsなので、スキーマ管理はmigration
新規アプリケーションのスキーマ変更も、
既存アプリケーションで管理

開発の複雑性増加!
なるべくテーブル作りたくない病に!(おいっ)

将来的には、データの整合性を取るために、
トランザクション管理しなくちゃいけなく・・



初期リリースが終わり、本格的な開発へ


既に先ほどの問題点が開発上の
大きなネックに!


このままだと、
かなり早期に負の遺産化されてしまう!!
アーキテクチャーを変えることに

要件:

・ユーザー認証処理
・共有カラムの切り出し(name, email など)
なるべく早く!!


英語でも探したけれど、
ありそうなケースなのに、意外と知見が見つからない

そこで、検討した3つの案

案1    Userのみを API化

○メリット: 工数が短い
○デメリット:
  ・Userのスキーマが既存APPにあるという問題は未解消
  ・パフォーマンスが悪い

案2  ユーザー認証をOAuth化

○メリット: とても疎結合
○デメリット:
 ・開発工数が長そう(ちょっと大掛かり)
  ・共通のカラムを持つという要件を簡単には満たせない
 
案3 ユーザーをRails Engine化してマウント
○メリット: アプリケーションレイヤでの抽象化なので
認証以外にも応用できそう
○デメリット:  できるの?
(DBをテーブルごとに切り替える必要がある)

補足: Rails Engineとは?


Railsアプリケーションを再利用可能にするように、

本体にマウント可能にする


↑↓

プラグイン、gem


・Rackミドルウェアである

・routes, task等を独自に記述できる

などなど





実装リスクを洗い出し、工数見積を出すため


案2・案3でプロトタイプ実装を試みる


結果


案2:

OAuth providerを作るgem(doorkeeper)を使ってできた

案3:

 ActiveRecord establish_connectionでDBを変えれた

複数DBは、本体でテストも書かれているので大丈夫そう


では、どちらにするか?


工数はあまり変わらなさそう・・


案2 OAuth化(HTTPレイヤ)

・OAuth Provider化しても外部公開の予定はない

=要件に対して、オーバースペック


案3 Rails Engine化(アプリケーションレイヤ)

・応用範囲が広そう

→共通マスタの切り出し、など


結論:案3でやってみよう!

ということで、engineを現在作成中!

→(追記)できました


なるべく使っていることを意識しないように隠蔽!

=アプリケーションの改修コストを減らす


(実際のAPI)

  

将来的なengineの全体像


認証ロジックの他に、

・共通マスタ

・共通ライブラリ

・ユーザーのロール(権限)管理


などを持たせる予定


”他にもいいプラクティスがあるかもしれないので、

「こういうやり方があるよ!」などの

ご意見があったらぜひお聞かせください!”






ご静聴ありがとうございました!
Made with Slides.com