Cookie-Überlauf in der Schienenanwendung?

105

ActionDispatch :: Cookies :: CookieOverflow in UsersController # create

Ich habe diesen Fehler, wenn ich versuche, die Seite zu öffnen. Ich weiß nicht, wie ich diesen Fehler beheben soll. Haben Sie einen Vorschlag für dieses Problem?

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
erogol
quelle
1
Dieser Fehler tritt auf, wenn sich große Datenmengen / Objekte in der Sitzung befinden. Können Sie den Code zum Erstellen einer Aktion im Controller freigeben?
Naren Sisodiya
3
Während die Antworten zum Ändern Ihres Sitzungsspeichers korrekt sind, würde ich fragen, warum Sie den gesamten Benutzer in der Sitzung speichern möchten. Wenn Sie etwas speichern müssen, speichern Sie die user_id (obwohl das bereits in Ihrem Cookie ist)
Frederick Cheung
Gehen Sie einfach zum Browser-Cache-Store und löschen Sie Cookies, die zu dieser bestimmten Website-URL gehören. für mich passiert es meistens in localhost.
Ben
Ich hatte ein Benutzermodell mit erstellt Deviseund meinen Entwicklungsserver nach dem Ausführen der Migrationen nicht neu gestartet. Sobald ich dies tat, hörte der Fehler auf.
Wuliwong

Antworten:

159

Sie haben ein Limit von 4 KB für das, was Sie in einem Cookie speichern können, und wenn Rails Ihr Objekt zum Schreiben in das Cookie in Text konvertiert, ist es wahrscheinlich größer als dieses Limit.

Ruby on Rails ActionDispatch::Cookies::CookieOverflow Fehler

Auf diese Weise das CookieOverflow Fehler auf.

Der einfachste Weg, dieses Problem zu lösen, besteht darin, dass Sie Ihren session_store ändern müssen und den nicht verwenden cookie_store. Sie können das active_record_storeBeispiel verwenden.

Hier sind die Schritte

  1. Generieren Sie eine Migration, die die Sitzungstabelle erstellt

    rake db:sessions:create
  2. Führen Sie die Migration aus

    rake db:migrate
  3. Ändern config/initializers/session_store.rbvon

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

    zu

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

Wenn Sie die drei Schritte ausgeführt haben, starten Sie Ihre Anwendung neu. Rails verwendet jetzt die Sitzungstabelle zum Speichern von Sitzungsdaten, und Sie haben nicht das 4-KB-Limit.

AMIC MING
quelle
1
ist es möglich, diesen Cookie zu sehen, um dies zu überprüfen
erogol
nur neugierig - ist das ein Limit von 4 KB pro Sitzung oder pro App?
Colllin
1
@colllin, es ist pro Sitzung.
Alex D
brauche ich den active_record_storeEdelstein?
Saad Masood
oder ist es Teil von Rails4
Saad Masood
78

Damit die :active_record_storeFunktionalität in Rails 4/5 funktioniert, müssen Sie das Juwel activerecord-session_store zu Ihrem Gemfile:

gem 'activerecord-session_store'

Führen Sie dann den Migrationsgenerator aus:

rails generate active_record:session_migration
rake db:migrate

Und schließlich stellen Sie Ihren Sitzungsspeicher ein in config/initializers/session_store.rb:

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

AKTUALISIEREN:

Wenn jemand null value in column "session_id" violates not-null constraintin Rails 4 eine Nachricht empfängt , gibt es eine Problemumgehung in Github (nicht getestet). Sie müssen einen Initialisierer mit erstellenActiveRecord::SessionStore::Session.attr_accessible :data, :session_id

Alter Lagos
quelle
Haben Sie bei der Verwendung dieses Edelsteins keinen Fehler erhalten? Ich bekomme folgendes:ERROR: null value in column "session_id" violates not-null constraint
Peter
@Peter Es ist mir nicht passiert, aber hier erscheint immer noch als offenes Thema. Mein einziger Rat ist, einen Kommentar in diese Ausgabe zu schreiben, um ihn anzusehen, bis jemand eine Lösung gefunden hat. Entschuldigung: /
Alter Lagos
@ Peter Ich bin nicht sicher, ob es zu spät ist, aber überprüfen Sie trotzdem meine aktualisierte Antwort
Alter Lagos
2
Nach dem Ausführen von "Rails generieren Active_Rekord: Session_Migration" vergessen Sie nicht, Folgendes auszuführen: "Rake DB: Migrieren"!
Patrice Gagnon
2
Was ist, wenn ich nichts in der Datenbank speichern möchte, wie ich den Fehler beheben kann? Ich habe Rescue_from ActionDispatch :: Cookies :: CookieOverflow ,: with =>: render_404 im ApplicationController versucht, aber es hat nicht funktioniert
Nisevi
14

Wenn dies angezeigt wird, stellen Sie sicher, dass einige Sitzungsdaten nicht in die Luft gesprengt werden. In meinem Fall wurden Tausende derselben Nachricht in die Flash-Nachricht gepumpt. Nur sagen.

Ich füge hinzu, wenn Sie der Meinung sind, dass die Lösung darin besteht, Ihren Cookie-Speicher zu vergrößern (wie die meisten anderen Antworten), sollten Sie wahrscheinlich besser überdenken, was Sie tatsächlich in Cookies einfügen. Wenn Sie mehr als ein paar Authentifizierungstoken, Sitzungs-IDs und möglicherweise ein paar Layout- / Tracking-Cookies benötigen, leben Sie in den 90er Jahren.

David Hempy
quelle
1
Ich habe einige Parameter tief zusammengeführt, um den Zustand zu retten!
Anwar
2
Dies war auch für mich die Fehlerursache. Zu viele Daten in die Flash-Nachricht einfügen.
Knubie
10

Es ist keine gute Idee, ein Modellobjekt in der Sitzung zu speichern.

Schauen Sie sich diesen Railscast zu diesem Thema an: http://railscasts.com/episodes/13-dangers-of-model-in-session?autoplay=true

Es ist besser, die ID (in diesem Fall die Benutzer-ID) in der Sitzung zu speichern. Dann haben Sie dieses Problem nicht.

(Siehe auch den Kommentar von Frederick Cheung oben).

Zack Xu
quelle
9

Die Fehlermeldung zeigt deutlich das Problem mit der Größe des Cookie-Speichers an, das überläuft.

Ihre Sitzungen (standardmäßig in Cookies) müssen in den aktiven Datensatzspeicher oder Memcache-Speicher verschoben werden, um dieses Problem zu beheben.

Für Datenbanksitzungen:

config.action_controller.session_store = :active_record_store

Sie müssen die Sitzungstabelle wie folgt erstellen

rake db:sessions:create
rake db:migrate

ODER

Für Memcache-Sitzungen:

config.action_controller.session_store = :mem_cache_store

Außerdem müssen Sie einen Mem-Cache-Server einrichten und wie folgt konfigurieren:

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

Dieser Fehler liegt daran, dass Sie versuchen, das Benutzermodell zu serialisieren. Wenn Sie ein Objekt in einem Cookie speichern, verwenden Rails Marshal.dump das eine große Menge an Inhalten erzeugen kann, da alles im Benutzerdatensatz enthalten ist

Anstatt den tatsächlichen Benutzerdatensatz mit dem session[:current_user] = userVersuch zu speichern, nur die Benutzer-ID zu speichern, haben Sie eine Methode, mit der Sie den Benutzer nachschlagen können, z

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

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

Dieser Fehler trat bei mir auf, als ich eine Spezifikation ausführte. Nach dem Update von Capybara von 1.x auf 2.x. Harken Sie einfach tmp: klar gelöst.

Artur79
quelle