Desbordamiento de cookies en la aplicación de rieles?

106

ActionDispatch :: Cookies :: CookieOverflow en UsersController # create

Tengo este error cuando intento abrir la página. No sé cómo depurar este error. ¿Tiene alguna sugerencia para este 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
erogol
fuente
1
este error se produce cuando tiene un objeto / datos grandes en la sesión. ¿Puedes compartir el código para crear acción en el controlador?
Naren Sisodiya
1
¿Duplicado de stackoverflow.com/questions/4782611/… ?
iblue
3
Si bien las respuestas sobre cómo cambiar la tienda de sesiones son correctas, me preguntaría por qué desea almacenar todo el usuario en la sesión. Si tiene que almacenar algo, almacene el user_id (aunque ya está en su cookie)
Frederick Cheung
Simplemente vaya a la tienda de caché del navegador y borre las cookies que pertenecen a esa URL específica del sitio web. para mí ocurre principalmente en localhost.
ben
Había creado un modelo de usuario con Devisey no había reiniciado mi servidor de desarrollo después de ejecutar las migraciones. Una vez que lo hice, el error se detuvo.
wuliwong

Respuestas:

159

Tiene un límite de 4kb sobre lo que puede almacenar en una cookie, y cuando Rails convierte su objeto en texto para escribir en la cookie, probablemente sea mayor que ese límite.

ActionDispatch::Cookies::CookieOverflowError de Ruby on Rails

De esa forma se CookieOverflowproduce este error.

La forma más sencilla de resolver este problema es cambiar su session_store y no usar el cookie_store. Puede utilizar el active_record_storeejemplo.

Aquí están los pasos

  1. Genera una migración que crea la tabla de sesiones.

    rake db:sessions:create
  2. Ejecuta la migración

    rake db:migrate
  3. Modificar config/initializers/session_store.rbdesde

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

    a

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

Una vez que haya realizado los tres pasos, reinicie su aplicación. Rails ahora usará la tabla de sesiones para almacenar datos de sesión, y no tendrá el límite de 4kb.

AMIC MING
fuente
1
¿Es posible ver esa cookie para verificar esto
Erogol
solo curiosidad, ¿es este un límite de 4kb por sesión o por aplicación?
colllin
1
@colllin, es por sesión.
Alex D
¿Necesito la active_record_storegema?
Saad Masood
o es parte de rails4
Saad Masood
78

Para que la :active_record_storefuncionalidad funcione en Rails 4/5, debe agregar la gema activerecord-session_store a su Gemfile:

gem 'activerecord-session_store'

luego ejecute el generador de migración:

rails generate active_record:session_migration
rake db:migrate

Y finalmente configure su tienda de sesiones en config/initializers/session_store.rb:

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

ACTUALIZAR:

Si alguien recibe un null value in column "session_id" violates not-null constraintmensaje en rails 4, hay una solución en github (no probada). Debes crear un inicializador conActiveRecord::SessionStore::Session.attr_accessible :data, :session_id

Alter Lagos
fuente
¿No recibiste un error al usar esta gema? Recibo lo siguiente:ERROR: null value in column "session_id" violates not-null constraint
Peter
@Peter No me pasó a mí, pero aquí todavía aparece como un tema abierto. Mi único consejo es escribir un comentario en ese número para verlo hasta que alguien ponga una solución. Lo siento: /
Alter Lagos
@Peter No estoy seguro de si es demasiado tarde, pero de todos modos verifique mi respuesta actualizada
Alter Lagos
2
Después de ejecutar "rails generate active_record: session_migration" ¡no olvide ejecutar: "rake db: migrate"!
Patrice Gagnon
2
¿Qué pasa si no quiero almacenar nada en la base de datos, cómo puedo rescatar el error? Intenté rescue_from ActionDispatch :: Cookies :: CookieOverflow,: with =>: render_404 en ApplicationController pero no funcionó
nisevi
14

Si está viendo esto, verifique que no esté explotando algunos datos de la sesión. En mi caso, fueron miles del mismo mensaje bombeado al mensaje flash. Solo digo.

Agregaré que si cree que la solución es hacer que su tienda de cookies sea más grande (como se aborda la mayoría de las otras respuestas), probablemente sea mejor que reconsidere lo que realmente está poniendo en las cookies. Si necesita más de un par de tokens de autenticación, ID de sesión y tal vez algunas cookies de diseño / seguimiento, está viviendo en los años 90.

David Hempy
fuente
1
¡Estaba fusionando profundamente algunos parámetros para salvar el estado!
Anwar
2
Esta fue la causa del error para mí también. Poner demasiados datos en el mensaje flash.
Knubie
10

No es una buena idea almacenar un objeto modelo en la sesión.

Vea este railscast sobre este tema: http://railscasts.com/episodios/13-dangers-of-model-in-session?autoplay=true

Es una mejor práctica almacenar la identificación (identificación del usuario en este caso) dentro de la sesión. Entonces no tendrás este problema.

(Véase también el comentario anterior de Frederick Cheung).

Zack Xu
fuente
9

el mensaje de error indica claramente el problema con el tamaño de la tienda de cookies que se desborda.

Sus sesiones (de forma predeterminada en cookies) deben trasladarse a la tienda de registros activa o la tienda de Memcache para solucionar este problema.

Para sesiones basadas en datos:

config.action_controller.session_store = :active_record_store

Necesita crear la tabla de sesiones como se muestra a continuación

rake db:sessions:create
rake db:migrate

O

Para sesiones de Memcache:

config.action_controller.session_store = :mem_cache_store

También necesita configurar un servidor de memoria caché y configurarlo de la siguiente manera:

config.cache_store = :mem_cache_store, 'localhost', '127.0.0.1:11211',
{:namespace => 'myapp123'}
Dios mío
fuente
6

Ese error se debe a que está intentando serializar el modelo de usuario. Al almacenar un objeto en una cookie, los rieles utilizarán Marshal.dump, que puede producir una gran cantidad de contenido, ya que está todo en el registro del usuario.

En lugar de almacenar el registro de usuario real, session[:current_user] = userintente simplemente almacenar la ID de los usuarios, luego tenga un método un método para buscar al usuario a partir de eso, por ejemplo

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

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

Este error apareció para mí cuando estaba ejecutando especificaciones. Después de actualizar Capybara de 1.xa 2.x. Solo rake tmp: clear lo resolvió.

Artur79
fuente