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の全体像


認証ロジックの他に、

・共通マスタ

・共通ライブラリ

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


などを持たせる予定


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

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

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






ご静聴ありがとうございました!

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

By chikahiro tokoro

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

  • 8,722