4

単一のラックアプリケーションで(異なるパスまたはドメインの)複数のセッションCookieをどのように操作できますか?

たとえば、3つの場所を使用する次のアプリケーションについて考えてみます。

  • www.my-app.net=>メインアプリ
  • www.my-app.net/app_a=>サブアプリA
  • app_b.my_app.net/=>サブアプリB

3つのセッションCookieと対話できる必要があります。

  • domain = www.my-app.net; パス=/;
  • domain = www.my-app.net; path = / app_a;
  • domain = app_b.my-app.net /; パス=/;

Rack :: Session :: Cookieは良い選択のように見えましたが、ミドルウェアとして、セッションCookieをconfig.ruに設定する必要があり、ラックアプリケーションごとに1つのセッションCookieに制限されているようです。

この特殊なケースでは、メインラックアプリケーションポイントはサブアプリケーションを簡単に追加することであるため、アプリケーションを複数のラックアプリケーションに分割してRack :: Session::Cookieを使用することは実行可能なソリューションではありません。

理想は、ラックアプリケーションコード内から複数のセッションCookieと自由に対話する方法です。

今のところ、私は検討しています:

  • 複数のセッションCookieとの相互作用を可能にするミドルウェアを作成する
  • CGI :: Cookieを使用して、アプリケーション内にカスタムセッションCookie管理を実装します

しかし、どちらも非常に面倒なので、この機能を実現するためのより簡単な方法があるかどうか疑問に思いました。

アドバイスや提案を事前に感謝します。

4

1 に答える 1

3

誰かが同じニーズで実行している場合は、アプリケーション内でセッションを管理するためのクラスを作成するのが最も簡単な方法であることがわかりました。

Rack ::Utilsには2つの優れたショートカットがあります。Rack::Utils.set_cookie_header!およびUtils.delete_cookie_header!これにより、Cookieを処理する際の作業が非常に簡単になります。

アプリケーションを使用してデータベースにセッションを保存していますが、別のバックエンドをサポートするのは簡単なはずです。

補足として、私が持ってきたいくつかの考慮事項:

  • Cookieの名前が有効であることを確認するために、その目的でサブアプリケーション名のsha-1を使用しています。
  • SecureRandom.urlsafe_base64は、セッションキーの生成に役立ちます。
  • セッションのクリーニングと更新は手動で実装する必要があります。

サンプルコード

クッキーを管理するクラス、コミット機能は、ラックにクッキーを設定および削除します。

class Framework::Response::Cookies

  def set( params )
    @cookies[params.delete( :name )] = params
  end

  def remove( params )
    @remove_cookies[params.delete( :name )] = params
  end

  def commit( headers )
    @cookies.each_pair do |name, params|
      Rack::Utils.set_cookie_header!( headers, name, params )
    end
    @remove_cookies.each_pair do |name, params|
      Rack::Utils.delete_cookie_header!( headers, name, params )
    end
  end

end

セッションを管理するクラス(バックエンドとしてMongoを使用):

class Database::Mongo::Session < Session

  def save
    expire = Time.now + @session_ttl
    @framework.content.db.find_and_modify( self.collection_name, { 
      :query => { :name => @session_name, :id => @session_id }, 
      :update => { :expire => expire, :name => @session_name, :id => @new_session_id || @session_id , :variables => @variables.to_hash },
      :upsert => true 
    })
    @framework.response.cookies.set( 
      :name => @session_name,
      :value => @new_session_id || @session_id,
      :path => @framework.applications.active.active_request['path'],
      :domain => @framework.applications.active.active_request['host'],
      :httponly => true  
    )
  end

  def delete
    @framework.content.db.remove( self.collection_name, { :id => @session_id } )
    @framework.response.cookies.remove( :name => @session_name )
  end

end

が呼び出されるたび@framework.response.cookies.setに、CookieデータがFramework::Response::Cookiesクラス@cookies変数にプッシュされます。

応答を提供する前に、Framework::Response::Cookies.commitを使用してCookieをコミットするための呼び出しRack::Utils

于 2012-11-05T02:28:18.827 に答える