2012-04-18 11 views
28

私はできる限りモジュール化したままで自分のレールアプリを開発してきました。私はサービスの下にさまざまな部分を実装しようとしています。
a)は、ユーザが壁、柱など
b)の写真を保存するPhotoAppを持つことができますMainAppに、可能に彼の写真を表示するには、ユーザー: 複数のアプリケーション/サーバー間でのRails認証

はフェイスブックの一例を言いますこれは、MainAppでも使用できるREST APIを持つスタンドアロンアプリです。

OAuthをシングルサインオンソリューション(このチュートリアルのようにhttp://blog.joshsoftware.com/2010/12/16/multiple-applications-with-devise-omniauth-and-single-sign-on/)として使用することを考えていましたが、各アプリケーションはOAuth経由で承認され、Cookieに基づいて現在のユーザーセッションにアクセスします。

最初の質問:これは実行可能な解決策ですか?

2番目の質問:私はMainAppにサーバー(いないユーザーのブラウザから)からPhotoApp APIを呼び出すことができるようにしたいです。この状況で認証はどのように機能しますか?

3番目の質問:どうだろう、この作品、私はNode.jsのを使用したサービスを持っていたと言いますか?

+0

このようなシナリオの実装に役立つ[Oauth Servers](http://www.knight.io/categories/oauth-servers-ruby)がいくつかあります。 –

答えて

20

はい、OAuthを使用したSSOは実行可能なソリューションですが、最も単純なものではありません。新しいものを作るときは、OAuth 2.0が道です。 OAuth標準は、多くの根拠をカバーしています。

OAuthの主な利点は、は、ユーザーがサードパーティのアプリケーションにパスワードを開示せずに自分のアカウントにアクセスできるようにすることです。このような相互運用性を真剣に提供していないのであれば、おそらくOAuthはおそらく過剰です。複雑さを考えると

は、私は解決策の異なるペアを提供します:

シングルサインオンのために

トリックが共有セッションを使用するようにドメイン&内のホスト間のセッションIDクッキーを共有することです

すべてのRailsアプリケーションには、Cookieに署名するための「秘密」があります。より新しいRailsアプリでは、これは/config/initializers/secret_token.rbにあります。各アプリケーションに同じ秘密トークンを設定します。

その後、すべてのサブドメインからのアクセスを許可するようにセッションを構成:内部APIについて

AppName::Application.config.session_store :active_record_store, :key => '_app_name_session', :domain => :all 

をHTTPS接続を経由の認証に良い共有秘密を使用し

を呼び出します。秘密を「Authorization」ヘッダー値に渡します。

共有シークレットは、他のアーキテクチャ(node.jsなど)でも簡単に使用できます。常にHTTPSを使用するようにしてください。そうしないと、共有秘密情報がネットワーク上で盗聴される可能性があります。

+1

セッションIDを共有することはSSOにとっては良いスタートのようですが、そこでは停止します。ここには大量の実装の詳細が残っています。ログイン中にアプリはどのように認証されますか?アプリはログインユーザーの能力をどのようにして知るのですか? – Fitzsimmons

+1

はい、完全なSSOソリューションを実装する際には、設計することがたくさんあります。中央認証サービスを作成することはおそらく良いスタートですが、StackOverflowの答えを超えています...おそらく、O'Reillyの本のようになります。 – Mars

+0

これは、すべてのドメインが共通のtld /サブドメインを共有していることを前提としています。異なるtldについてはどうですか? – lukad

3

最近、私はRailsとErlangアプリケーションの間でセッションデータを共有したいという同様の問題がありました。私の解決策は、セッションをRedisに保存したクラスRack::Session::Abstract::IDをハッシュvaulesとして書くことでした。 StringタイプのMarshal.dumpは呼び出しません。これにより、非ルビアプリケーションがsession_idのセッション値の一部を使用できるようになります。あなたが呼び出したい場合は

redis.hgetall("rack.session:#{session_id}") 

:で

use MaybeMarshalRedisSession 

、他の場所から:とラックから

MyApp::Application.config.session_store MaybeMarshalRedisSession 

:あなたがしてレールからこれを使用することができます

require 'rack/session/abstract/id' 

class MaybeMarshalRedisSession < Rack::Session::Abstract::ID 

    def initialize(app, options = {}) 
    @redis = options.delete(:redis) || Redis.current 
    @expiry = options[:expire_after] ||= (60 * 60 * 24) 
    @prefix = options[:key] || 'rack.session' 
    @session_key = "#{@prefix}:%s" 
    super 
    end 

    def get_session(env, sid) 
    sid ||= generate_sid 
    session = @redis.hgetall(@session_key % sid) 
    session.each_pair do |key, value| 
     session[key] = begin 
     Marshal.load(value) 
     rescue TypeError 
     value 
     end 
    end 

    [sid, session] 
    end 

    def set_session(env, sid, session, options={}) 
    @redis.multi do 
     session.each_pair do |key, value| 
     # keep string values bare so other languages can read them 
     value = value.is_a?(String) ? value : Marshal.dump(value) 
     @redis.hset(@session_key % sid, key, value) 
     end 
     @redis.expire(@session_key % sid, @expiry) 
    end 

    sid 
    end 

    def destroy_session(env, sid, option={}) 
    @redis.del(@session_key % sid) 
    generate_sid unless options[:drop] 
    end 

end 

あなたのMainAppまたはNode.jsのPhotoAppあなたのユーザーのセッションCookieを含むHTTPリクエストを作成できます。

3

2014年のRailsConf中にOctolabsのJeremy Greenが提案したサービス指向アーキテクチャーのソリューションを見ることができます。

(などのレポ、デモ、)すべてのリソースを持つブログ記事がここにあります。http://www.octolabs.com/so-auth

、すべてを説明したビデオはここにある:http://www.youtube.com/watch?v=L1B_HpCW8bs

この集中型のSSOは、簡単な作業ではありませんが、 Jeremyはサービス指向アーキテクチャーについて話し、このシステムをどのように組み合わせるかを正確に共有する優れた仕事をしました。

関連する問題