Débordement de cookie dans l'application rails?

106

ActionDispatch :: Cookies :: CookieOverflow dans UsersController # create

J'ai cette erreur lorsque j'essaye d'ouvrir la page. Je ne sais pas comment déboguer cette erreur. Avez-vous des suggestions pour ce problème?

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
érogol
la source
1
cette erreur survient lorsque vous avez un gros objet / données en session. Pouvez-vous partager le code pour créer une action dans le contrôleur?
Naren Sisodiya
3
Bien que les réponses sur la modification de votre magasin de session soient correctes, je me demande pourquoi vous souhaitez stocker l'ensemble de l'utilisateur dans la session. Si vous devez stocker quelque chose, stockez le user_id (bien qu'il soit déjà dans votre cookie)
Frederick Cheung
Accédez simplement à la mémoire cache du navigateur et effacez les cookies appartenant à l'URL de ce site Web spécifique. pour moi, cela se produit principalement dans localhost.
ben
J'avais créé un modèle utilisateur avec Deviseet je n'avais pas redémarré mon serveur de développement après avoir exécuté les migrations. Une fois que je l'ai fait, l'erreur s'est arrêtée.
wuliwong

Réponses:

159

Vous avez une limite de 4 Ko sur ce que vous pouvez stocker dans un cookie, et lorsque Rails convertit votre objet en texte pour l'écrire dans le cookie, il est probablement plus grand que cette limite.

ActionDispatch::Cookies::CookieOverflowErreur Ruby on Rails

De cette façon, cette CookieOverflowerreur se produit.

Le moyen le plus simple de résoudre celui-ci est de changer votre session_store et de ne pas utiliser le fichier cookie_store. Vous pouvez utiliser l' active_record_storeexemple par.

Voici les étapes

  1. Générer une migration qui crée la table de session

    rake db:sessions:create
  2. Exécutez la migration

    rake db:migrate
  3. Modifier à config/initializers/session_store.rbpartir de

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

    à

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

Une fois que vous avez effectué les trois étapes, redémarrez votre application. Rails utilisera désormais la table des sessions pour stocker les données de session, et vous n'aurez pas la limite de 4 Ko.

AMIC MING
la source
1
est-il possible de voir ce cookie pour vérifier cela
erogol
juste curieux - est-ce une limite de 4 Ko par session ou par application?
colllin
1
@colllin, c'est par session.
Alex D
ai-je besoin du active_record_storebijou?
Saad Masood
ou fait-il partie de rails4
Saad Masood
78

Pour que la :active_record_storefonctionnalité fonctionne dans Rails 4/5, vous devez ajouter le gem activerecord-session_store à votre Gemfile:

gem 'activerecord-session_store'

puis exécutez le générateur de migration:

rails generate active_record:session_migration
rake db:migrate

Et enfin, configurez votre magasin de session dans config/initializers/session_store.rb:

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

METTRE À JOUR:

Si quelqu'un reçoit un null value in column "session_id" violates not-null constraintmessage dans les rails 4, il existe une solution de contournement dans github (non testée). Vous devez créer un initialiseur avecActiveRecord::SessionStore::Session.attr_accessible :data, :session_id

Alter Lagos
la source
N'avez-vous pas reçu d'erreur lors de l'utilisation de cette gemme? J'obtiens ce qui suit:ERROR: null value in column "session_id" violates not-null constraint
Peter le
@Peter Cela ne m'est pas arrivé, mais ici apparaît toujours comme un problème ouvert. Mon seul conseil est d'écrire un commentaire sur ce problème pour le regarder jusqu'à ce que quelqu'un mette un correctif. Désolé: /
Alter Lagos
@Peter Je ne sais pas s'il est trop tard, mais vérifiez quand même ma réponse mise à jour
Alter Lagos
2
Après avoir lancé "rails generate active_record: session_migration", n'oubliez pas de lancer: "rake db: migrate"!
Patrice Gagnon
2
que faire si je ne veux rien stocker dans la base de données, comment puis-je récupérer l'erreur? J'ai essayé rescue_from ActionDispatch :: Cookies :: CookieOverflow,: with =>: render_404 dans ApplicationController mais cela n'a pas fonctionné
nisevi
14

Si vous voyez cela, vérifiez que vous ne gonflez pas certaines données de session. Dans mon cas, c'était des milliers du même message pompé dans le message flash. Juste dire.

J'ajouterai que si vous pensez que la solution est d'agrandir votre magasin de cookies (comme la plupart des autres adresses de réponses), vous feriez probablement mieux de repenser ce que vous mettez réellement dans les cookies. Si vous avez besoin de plus de quelques jetons d'authentification, d'identifiants de session et peut-être de quelques cookies de mise en page / suivi, vous vivez dans les années 90.

David Hempy
la source
1
J'étais en train de fusionner en profondeur certains paramètres pour enregistrer l'état!
Anwar
2
C'était aussi la cause de l'erreur pour moi. Mettre trop de données dans le message flash.
knubie
10

Ce n'est pas une bonne idée de stocker un objet modèle dans la session.

Découvrez ce railscast sur ce sujet: http://railscasts.com/episodes/13-dangers-of-model-in-session?autoplay=true

Il est préférable de stocker l'identifiant (l'identifiant de l'utilisateur dans ce cas) dans la session. Alors vous n'aurez pas ce problème.

(Voir également le commentaire de Frederick Cheung ci-dessus).

Zack Xu
la source
9

le message d'erreur indique clairement le problème avec la taille du magasin de cookies qui déborde.

Vos sessions (par défaut dans le cookie) doivent être déplacées vers Active Record Store ou Memcache Store pour résoudre ce problème.

Pour les sessions basées sur les données:

config.action_controller.session_store = :active_record_store

Vous devez créer la table de session comme ci-dessous

rake db:sessions:create
rake db:migrate

OU

Pour les sessions Memcache:

config.action_controller.session_store = :mem_cache_store

Vous devez également configurer un serveur de cache mémoire et le configurer comme ci-dessous:

config.cache_store = :mem_cache_store, 'localhost', '127.0.0.1:11211',
{:namespace => 'myapp123'}
Mon Dieu
la source
6

Cette erreur est due au fait que vous essayez de sérialiser le modèle utilisateur Lors du stockage d'un objet dans un cookie, les rails utiliseront Marshal.dump, ce qui peut produire une grande quantité de contenu, car tout se trouve sur l'enregistrement utilisateur

Au lieu de stocker l'enregistrement d'utilisateur réel avec session[:current_user] = useressayez simplement de stocker l'ID de l'utilisateur, alors ayez une méthode une méthode pour rechercher l'utilisateur à partir de cela, par exemple

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

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

Cette erreur est apparue pour moi lorsque j'exécutais des spécifications. Après avoir mis à jour Capybara de 1.x à 2.x. Juste râteau tmp: clear l'a résolu.

Artur79
la source