Cookie overflow nell'applicazione rail?


106

ActionDispatch :: Cookies :: CookieOverflow in UsersController # create

Ho questo errore quando provo ad aprire la pagina. Non so come eseguire il debug di questo errore. Hai qualche suggerimento per questo problema?

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
questo errore si verifica quando nella sessione sono presenti dati / oggetti di grandi dimensioni. Puoi condividere il codice per creare azione nel controller?
Naren Sisodiya,


3
Anche se le risposte sulla modifica del session store sono corrette, mi chiedo perché desideri memorizzare l'intero utente nella sessione. Se devi memorizzare qualcosa, salva user_id (anche se è già nel tuo cookie)
Frederick Cheung,

Basta andare al negozio di cache del browser e cancellare i cookie appartenenti a quello specifico URL del sito web. per me accade principalmente in localhost.
ben

Avevo creato un modello utente con Devisee non avevo riavviato il mio server di sviluppo dopo aver eseguito le migrazioni. Una volta fatto, l'errore si è fermato.
wuliwong

Risposte:


159

Hai un limite di 4kb su ciò che puoi memorizzare in un cookie e quando Rails converte il tuo oggetto in testo per la scrittura nel cookie è probabilmente più grande di quel limite.

ActionDispatch::Cookies::CookieOverflowErrore di Ruby on Rails

In questo modo si CookieOverflowverifica questo errore.

Il modo più semplice per risolvere questo problema è che devi cambiare il tuo session_store e non usare il file cookie_store. Puoi usare il active_record_storeby example.

Ecco i passaggi

  1. Genera una migrazione che crea la tabella della sessione

    rake db:sessions:create
  2. Esegui la migrazione

    rake db:migrate
  3. Modifica config/initializers/session_store.rbda

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

    per

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

Dopo aver eseguito i tre passaggi, riavvia l'applicazione. Rails ora utilizzerà la tabella delle sessioni per memorizzare i dati della sessione e non avrai il limite di 4kb.


1
è possibile vedere quel cookie per verificarlo
erogol

solo curioso: è un limite di 4kb per sessione o per app?
colllin

1
@colllin, è per sessione.
Alex D

ho bisogno della active_record_storegemma?
Saad Masood

o fa parte di rails4
Saad Masood

78

Per far :active_record_storefunzionare la funzionalità in Rails 4/5, devi aggiungere la gem activerecord-session_store al tuo Gemfile:

gem 'activerecord-session_store'

quindi esegui il generatore di migrazione:

rails generate active_record:session_migration
rake db:migrate

E infine imposta il tuo session store in config/initializers/session_store.rb:

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

AGGIORNARE:

Se qualcuno riceve un null value in column "session_id" violates not-null constraintmessaggio in rails 4, c'è una soluzione alternativa in github (non testato). È necessario creare un inizializzatore conActiveRecord::SessionStore::Session.attr_accessible :data, :session_id


Non hai ricevuto un errore durante l'utilizzo di questa gemma? Ricevo quanto segue:ERROR: null value in column "session_id" violates not-null constraint
Peter

@Peter Non è successo a me, ma qui appare ancora come un problema aperto. Il mio unico consiglio è scrivere un commento in quel numero per guardarlo fino a quando qualcuno non ha messo una correzione. Spiacenti: /
Alter Lagos

@Peter Non sono sicuro che sia troppo tardi, ma comunque controlla la mia risposta aggiornata
Alter Lagos

2
Dopo aver eseguito "rails generate active_record: session_migration" non dimenticare di eseguire: "rake db: migrate"!
Patrice Gagnon

2
cosa succede se non voglio memorizzare nulla nel DB come posso salvare l'errore? Ho provato rescue_from ActionDispatch :: Cookies :: CookieOverflow,: with =>: render_404 nell'ApplicationController ma non ha funzionato
nisevi

14

Se lo vedi, controlla di non far saltare in aria alcuni dati di sessione. Nel mio caso, erano migliaia dello stesso messaggio pompato nel messaggio flash. Sto solo dicendo.

Aggiungerò che se pensi che la soluzione sia ingrandire il tuo negozio di cookie (come la maggior parte delle altre risposte si rivolge), probabilmente faresti meglio a ripensare a cosa stai effettivamente inserendo nei cookie. Se hai bisogno di più di un paio di token di autenticazione, ID di sessione e forse alcuni cookie di layout / tracciamento, stai vivendo negli anni '90.


1
Stavo fondendo in profondità alcuni parametri per salvare lo stato!
Anwar

2
Questa è stata la causa dell'errore anche per me. Inserimento di troppi dati nel messaggio flash.
Knubie


9

il messaggio di errore indica chiaramente il problema con la dimensione del negozio di cookie che è in eccesso.

Le tue sessioni (per impostazione predefinita nei cookie) devono essere spostate nell'archivio dei record attivi o nell'archivio memcache per risolvere questo problema.

Per sessioni su database:

config.action_controller.session_store = :active_record_store

È necessario creare la tabella delle sessioni come di seguito

rake db:sessions:create
rake db:migrate

O

Per le sessioni Memcache:

config.action_controller.session_store = :mem_cache_store

Inoltre è necessario impostare un server mem cache e configurarlo come di seguito:

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

6

Questo erroreèperché stai tentando di serializzare il modello utente Quando memorizzi un oggetto in un cookie, rails userà Marshal.dump chepuò produrre una grande quantità di contenuto poichéètutto nel record dell'utente

Invece di memorizzare il record dell'utente effettivo con session[:current_user] = userprova a memorizzare l'ID dell'utente, quindi avere un metodo un metodo per cercare l'utente da quello, ad es.

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

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

1

Questo errore è apparso per me quando stavo eseguendo una specifica. Dopo aver aggiornato Capybara da 1.x a 2.x. Basta rake tmp: clear risolto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.