2010-11-25 10 views
11

私はなぜデータベースにセッションを保存するのだろうか?データベースにセッションを格納する利点はありますか? Webサービスが再起動されている場合は、セッションデータをロードバランスの取れた環境では)Rails:セッションをデータベースに格納する利点は?

2を失っていない、セッションデータが格納されている

1):

答えて

24

データベースまたはmemcachedの利点は、クライアント側でセッションデータを改ざんできず、クッキー(4kB)よりも多くのデータを保存できることです。

セッションがCookieまたはデータベースに格納されていて、Webサービスが再起動された場合、セッションデータは失われません。 memcachedに格納されている場合にのみ失われる可能性があります。

サーバーが負荷分散されている場合、セッションデータは要求を処理しているWebサーバーに渡されるため、Cookie、データベース、またはmemcachedセッションでは問題ありません。

memcachedまたはデータベースよりもクッキーの利点は、クライアントがセッションデータを保存しているため、サーバーがそれを担当していないことです。

セッション参照は引き続き維持する必要があるため、クッキーはクライアントとの間でやり取りされることに注意してください。

+0

「データは改ざんできません」を除いて、あなたが言うことはすべて正しいです。セッションハイジャック? – sethvargo

+3

セッションハイジャックでは、ユーザーはクライアント側のセッションデータを改ざんしていません。彼らは、認証されたユーザーであるかのように、システムにアクセスするためにセッションIDクッキーを複製しています。 –

+0

memcachedに保存されたセッションは、Webサーバーの再起動後に失われますか? –

18

私は考えることができる2つの理由があることですすべてのサーバーが要求を処理し、セッションデータにアクセスできることを意味します。

+0

多分。それは何らかのハッキングを保護していますか? – Zeck

+2

部分的には、クッキーにセッションデータを格納することにセキュリティの影響があります:http://guides.rubyonrails.org/security.html#session- storage – bmancini

+1

#2に関しては、デフォルトのクッキーベースのストレージにも同様の利点があります。それ自体の問題はありませんが、この利点はDB/Memcacheストレージに固有のものではありません。 – coreyward

7

私が考えることができる少なくとも3つの理由があります。 DBにセッションを保存すると、実行できるRailsインスタンスに簡単にアクセスできます。

  • したがって、複数のマシンを使用している場合は、セッションデータの配布について心配する必要はありません。
  • クッキーセッションストアを使用する場合にのみ使用する4kbのセッション制限セッションはありません。オブジェクトを格納するためにセッションを使用することは想定されていませんが、いつかその機能を使用できます。
  • RDBMを使用している場合(Memcachedや他の非永続ストレージではない場合)は、セッションデータが失われる心配はありません。
2

データベースにセッションを持たないことはあまり明白でなく、小さな利点は、現在のセッションをカウントして他のログインしているユーザーの名前を確認する必要がある場合、セッションデータまたはmemcachedを格納します。 2.9節で説明したように

+1

ウェブアプリケーションはステートレスであるため、とにかくログインしているユーザーの数を確認する信頼できる方法はありません。カウンティングセッションはそれを助けません。 –

+0

ページを読み込むたびにupdated_atパラメータをタッチすると、過去数日間に何種類のセッションが読み込まれたかがわかります。セッションクッキーの有効期限が24時間に設定されている場合は、ログインしているユーザーがわかります。また、セッションを削除してユーザーをログアウトすることもできます。 –

2

別の利点は、サーバー側のセッションの有効期限を処理することです:

http://guides.rubyonrails.org/security.html

「しかし、クライアントはWebブラウザがそのサーバー上のセッションを期限切れに格納されているクッキーを編集することができます」

class Session < ActiveRecord::Base 
    def self.sweep(time = 1.hour) 
    if time.is_a?(String) 
     time = time.split.inject { |count, unit| count.to_i.send(unit) } 
    end 

    delete_all "updated_at < '#{time.ago.to_s(:db)}' OR 
    created_at < '#{2.days.ago.to_s(:db)}'" 
    end 
end 
関連する問題