Przepełnienie pliku cookie w aplikacji railsowej?

106

ActionDispatch :: Cookies :: CookieOverflow w UsersController # create

Mam ten błąd, kiedy próbuję otworzyć stronę. Nie wiem, jak zdebugować ten błąd. Czy masz jakieś sugestie dotyczące tego problemu?

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
źródło
1
ten błąd pojawia się, gdy w sesji masz duże dane / obiekt. Czy możesz udostępnić kod do tworzenia akcji w kontrolerze?
Naren Sisodiya
1
Duplikat pliku stackoverflow.com/questions/4782611/… ?
iblue
3
Chociaż odpowiedzi dotyczące zmiany magazynu sesji są poprawne, zapytałbym, dlaczego chcesz przechowywać całego użytkownika w sesji. Jeśli musisz coś zapisać, zapisz user_id (chociaż jest już w twoim ciasteczku)
Frederick Cheung
Po prostu przejdź do magazynu pamięci podręcznej przeglądarki i wyczyść pliki cookie należące do tego konkretnego adresu URL witryny. dla mnie dzieje się to głównie w localhost.
Ben
Stworzyłem model użytkownika w programie Devisei nie zrestartowałem mojego serwera programistycznego po przeprowadzeniu migracji. Kiedy to zrobiłem, błąd ustał.
wuliwong

Odpowiedzi:

159

Masz limit 4kb na to, co możesz przechowywać w ciasteczku, a kiedy Railsy konwertują twój obiekt na tekst w celu zapisania w ciasteczku, prawdopodobnie jest większy niż ten limit.

ActionDispatch::Cookies::CookieOverflowBłąd Ruby on Rails

W ten sposób CookieOverflowpojawia się ten błąd.

Najłatwiejszym sposobem rozwiązania tego problemu jest zmiana pliku session_store i nie używanie rozszerzenia cookie_store. Możesz posłużyć się active_record_storeprzykładem.

Oto kroki

  1. Wygeneruj migrację, która tworzy tabelę sesji

    rake db:sessions:create
  2. Uruchom migrację

    rake db:migrate
  3. Modyfikuj config/initializers/session_store.rbz

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

    do

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

Po wykonaniu trzech kroków uruchom ponownie aplikację. Railsy będą teraz używać tabeli sesji do przechowywania danych sesji i nie będziesz mieć limitu 4kb.

AMIC MING
źródło
1
czy można zobaczyć ten plik cookie, aby to sprawdzić
erogol
tylko ciekawy - czy to jest limit 4 KB na sesję, czy na aplikację?
colllin
1
@colllin, to na sesję.
Alex D
czy potrzebuję active_record_storeklejnotu?
Saad Masood
czy też jest częścią rails4
Saad Masood
78

Aby :active_record_storefunkcjonalność działała w Railsach 4/5, musisz dodać gem activerecord-session_store do Gemfile:

gem 'activerecord-session_store'

następnie uruchom generator migracji:

rails generate active_record:session_migration
rake db:migrate

I na koniec ustaw swój magazyn sesji w config/initializers/session_store.rb:

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

AKTUALIZACJA:

Jeśli ktoś otrzymuje null value in column "session_id" violates not-null constraintwiadomość na rails 4, istnieje obejście tego problemu w githubie (nie testowane). Musisz utworzyć inicjator zActiveRecord::SessionStore::Session.attr_accessible :data, :session_id

Alter Lagos
źródło
Czy nie pojawił się błąd podczas korzystania z tego klejnotu? Otrzymuję następujące informacje:ERROR: null value in column "session_id" violates not-null constraint
Peter
@Peter To się nie zdarzyło, ale tutaj nadal pojawia się jako otwarty problem. Moją jedyną radą jest napisanie komentarza w tym numerze, aby obejrzeć go, dopóki ktoś nie naprawi. Przepraszamy: /
Alter Lagos
@Peter Nie jestem pewien, czy jest za późno, ale i tak sprawdź moją zaktualizowaną odpowiedź
Alter Lagos
2
Po uruchomieniu "rails generuje active_record: session_migration" nie zapomnij uruchomić: "rake db: migrate"!
Patrice Gagnon
2
co jeśli nie chcę niczego przechowywać w bazie danych, jak mogę uratować błąd? Próbowałem rescue_from ActionDispatch :: Cookies :: CookieOverflow,: with =>: render_404 w ApplicationController, ale to nie zadziałało
nisevi
14

Jeśli to widzisz, sprawdź, czy nie wysadzasz niektórych danych sesji. W moim przypadku były to tysiące tej samej wiadomości wpompowane w wiadomość flash. Tylko mówię.

Dodam, że jeśli uważasz, że rozwiązaniem jest powiększenie magazynu plików cookie (ponieważ większość innych odpowiedzi adresuje), prawdopodobnie lepiej przemyśleć, co tak naprawdę umieszczasz w plikach cookie. Jeśli potrzebujesz więcej niż kilku tokenów autoryzacji, identyfikatorów sesji i może kilku plików cookie układu / śledzenia, żyjesz w latach 90-tych.

David Hempy
źródło
1
Głęboko scalałem niektóre parametry, aby zapisać stan!
Anwar
2
To było przyczyną błędu również dla mnie. Umieszczanie zbyt dużej ilości danych w wiadomości flash.
knubie
10

Przechowywanie obiektu modelu w sesji nie jest dobrym pomysłem.

Sprawdź ten railscast na ten temat: http://railscasts.com/episodes/13-dangers-of-model-in-session?autoplay=true

Lepszą praktyką jest przechowywanie identyfikatora (w tym przypadku identyfikatora użytkownika) wewnątrz sesji. Wtedy nie będziesz miał tego problemu.

(Zobacz również komentarz Fredericka Cheunga powyżej).

Zack Xu
źródło
9

komunikat o błędzie wyraźnie wskazuje na problem z rozmiarem magazynu plików cookie, który jest przepełniony.

Twoje sesje (domyślnie w plikach cookie) muszą zostać przeniesione do magazynu Active Record lub memcache, aby rozwiązać ten problem.

W przypadku sesji opartych na danych:

config.action_controller.session_store = :active_record_store

Musisz utworzyć tabelę sesji, jak poniżej

rake db:sessions:create
rake db:migrate

LUB

W przypadku sesji Memcache:

config.action_controller.session_store = :mem_cache_store

Musisz także ustawić serwer pamięci podręcznej i skonfigurować go jak poniżej:

config.cache_store = :mem_cache_store, 'localhost', '127.0.0.1:11211',
{:namespace => 'myapp123'}
Mój Boże
źródło
6

Ten błąd jest spowodowany tym, że próbujesz serializować model użytkownika Podczas przechowywania obiektu w ciasteczku, szyny użyją Marshal.dump, który może wygenerować dużą ilość treści ponieważ jest to wszystko w rekordzie użytkownika

Zamiast przechowywać rzeczywisty rekord użytkownika, session[:current_user] = userspróbuj po prostu zapisać identyfikator użytkownika, a następnie użyj metody, aby wyszukać użytkownika z tego, np.

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

def current_user
  @current_user ||= User.find(session[:current_user_id])
end
cianmce
źródło
1

Ten błąd pojawił się podczas uruchamiania specyfikacji. Po aktualizacji Kapibary z 1.x do 2.x. Po prostu rake tmp: jasne rozwiązane.

Artur79
źródło