RailsアプリケーションでのCookieオーバーフロー?


105

UsersController#createのActionDispatch :: Cookies :: CookieOverflow

ページを開こうとすると、このエラーが発生します。このエラーをデバッグする方法がわかりません。この問題について何か提案はありますか?

def create
  @user = User.new(params[:user])
  sign_in @user

  if @user.save
    @user.folders.create(:folder_name=>"Default Folder", :user_id=>@user.id)
    flash[:success] = "Welcome to Bunch<it>! "
    redirect_to @user
  else
    @title = "Sign up"
    render 'new'
  end
end


def sign_in(user)
  cookies.permanent.signed[:remember_token] = [user.id, user.salt]
  session[:current_user] = user
  current_user = user
end

1
このエラーは、セッション中に大きなデータ/オブジェクトがある場合に発生します。コントローラでアクションを作成するためのコードを共有できますか?
Naren Sisodiya、2012


3
セッションストアの変更に関する答えは正しいですが、ユーザー全体をセッションに保存する理由を質問します。何かを保存する必要がある場合は、user_idを保存します(ただし、それは既にCookieに含まれています)
Frederick Cheung

ブラウザのキャッシュストアに移動し、その特定のWebサイトのURLに属するCookieをクリアするだけです。私にとってそれは主にlocalhostで発生します。
2015年

でユーザーモデルを作成しDevise、移行の実行後に開発サーバーを再起動していません。一度実行すると、エラーは停止しました。
ウリウォン2017

回答:


159

Cookieに保存できるものには4kbの制限があり、Railsがオブジェクトをテキストに変換してCookieに書き込む場合、おそらくその制限よりも大きくなります。

Ruby on Rails ActionDispatch::Cookies::CookieOverflowエラー

このようにして、このCookieOverflowエラーが発生します。

これを解決する最も簡単な方法は、session_storeを変更する必要があり、を使用しないことcookie_storeです。active_record_store例を使用できます。

手順は次のとおりです

  1. セッションテーブルを作成する移行を生成する

    rake db:sessions:create
  2. 移行を実行する

    rake db:migrate
  3. config/initializers/session_store.rbから変更

    (App)::Application.config.session_store :cookie_store, :key => 'xxx'

    (App)::Application.config.session_store :active_record_store

3つの手順を完了したら、アプリケーションを再起動します。これでRailsはセッションテーブルを使用してセッションデータを格納するようになり、4 KBの制限はなくなります。


1
これを確認するためにCookieを確認することは可能ですか
erogol

ちょうど好奇心が強い-これはセッションごと、またはアプリごとに4kbの制限ですか?
colllin 2013

1
@colllin、それはセッションごとです。
Alex D

active_record_store宝石は必要ですか?
Saad Masood

それともrails4の一部ですか
Saad Masood

78

:active_record_storeRails 4/5で機能を動作させるには、activerecord-session_store gemを以下に追加する必要がありますGemfile

gem 'activerecord-session_store'

次に移行ジェネレータを実行します。

rails generate active_record:session_migration
rake db:migrate

そして、最後にセッションストアを設定しますconfig/initializers/session_store.rb

Rails.application.config.session_store :active_record_store, :key => '_my_app_session'

更新:

null value in column "session_id" violates not-null constraintRails 4で誰かがメッセージを受信している場合は、githubに回避策があります(テストされていません)。あなたはイニシャライザを作成する必要がありますActiveRecord::SessionStore::Session.attr_accessible :data, :session_id


この宝石を使用するときにエラーが発生しませんでしたか?次のERROR: null value in column "session_id" violates not-null constraint
Peter

@ピーターそれは私には起こりませんでしたが、ここではまだ未解決の問題として表示されます。私の唯一の助言は、誰かが修正を加えるまでそれを見るためにその問題にコメントを書くことです。申し訳ありません:/
Alter Lagos

@ピーター手遅れかどうかはわかりませんが、とにかく私の最新の回答をチェックしてください
Alter Lagos

2
「rails generate active_record:session_migration」を実行した後、「rake db:migrate」を実行することを忘れないでください!
Patrice Gagnon、2014年

2
DBに何も保存したくない場合、どうすればエラーを救出できますか?ApplicationControllerでrescue_from ActionDispatch :: Cookies :: CookieOverflow、:with =>:render_404を試してみましたが、うまく
いき

14

これが表示される場合は、一部のセッションデータを爆発させていないことを確認してください。私の場合、それはフラッシュメッセージに送り込まれた何千もの同じメッセージでした。ただ言って。

ソリューションがCookieストアを大きくすること(他のほとんどの回答アドレスと同様)であると考えられる場合は、実際にCookieに入れるものを再考した方がよいでしょう。2つ以上の認証トークン、セッションID、およびいくつかのレイアウト/追跡Cookieが必要な場合は、90年代に住んでいます。


1
状態を保存するためにいくつかのパラメーターを深くマージしていました!
Anwar

2
これもエラーの原因でした。フラッシュメッセージにデータを入れすぎています。
knubie 2017年

10

セッションにモデルオブジェクトを格納することはお勧めできません。

このトピックに関するこのRailscastをチェックしてください:http ://railscasts.com/episodes/13-dangers-of-model-in-session?autoplay=true

セッション内にID(この場合はユーザーのID)を格納することをお勧めします。そうすれば、この問題は発生しません。

(上記のFrederick Cheungのコメントも参照してください)。


9

エラーメッセージは、オーバーフローするCookieストアサイズの問題を明確に示しています。

この問題を修正するには、セッション(デフォルトではcookie内)をアクティブレコードストアまたはmemcacheストアに移動する必要があります。

データベースセッションの場合:

config.action_controller.session_store = :active_record_store

以下のようにセッションテーブルを作成する必要があります

rake db:sessions:create
rake db:migrate

または

Memcacheセッションの場合:

config.action_controller.session_store = :mem_cache_store

また、memキャッシュサーバーをセットアップし、以下のように構成する必要があります。

config.cache_store = :mem_cache_store, 'localhost', '127.0.0.1:11211',
{:namespace => 'myapp123'}

6

そのエラーは、ユーザーモデルをシリアル化しようとしているためです。Cookieにオブジェクトを保存すると、RailsはMarshal.dumpを使用します。これは、ユーザーレコードのすべてであるため、大量のコンテンツを生成する可能性があります。

実際のユーザーレコードを保存する代わりにsession[:current_user] = user、ユーザーIDを保存するだけで、それからユーザーを検索するメソッドがあります。

def sign_in(user)
  ...
  session[:current_user_id] = user.id
end

def current_user
  @current_user ||= User.find(session[:current_user_id])
end

1

このエラーは、スペックを実行しているときに表示されました。カピバラを1.xから2.xに更新した後。tmp:clearをレーキするだけで解決しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.