Cookie在Rails应用程序中溢出?


106

UsersController#create中的ActionDispatch :: Cookies :: CookieOverflow

尝试打开页面时出现此错误。我不知道如何调试此错误。您对此问题有什么建议吗?

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
当会话中有大量数据/对象时,会出现此错误。您可以在控制器中共享用于创建操作的代码吗?
Naren Sisodiya 2012年


3
虽然有关更改会话存储的答案是正确的,但我想问为什么要在会话中存储整个用户。如果您必须存储某些内容,请存储user_id(尽管它已经在cookie中)
Frederick Cheung

只需转到浏览器缓存存储,然后清除属于该特定网站URL的cookie。对我来说,它主要发生在本地主机。
2015年

我创建了一个用户模型,Devise并且在运行迁移后没有重新启动开发服务器。一旦我做了,错误就停止了。
wuliwong

Answers:


159

您在cookie中可以存储的内容有4kb的限制,并且当Rails将您的对象转换为用于写入cookie的文本时,它可能大于该限制。

Ruby on Rails ActionDispatch::Cookies::CookieOverflow错误

这样 CookieOverflow就会发生错误。

解决此问题的最简单方法是,您需要更改session_store而不使用cookie_store。您可以使用active_record_store通过示例。

这是步骤

  1. 生成迁移以创建会话表

    rake db:sessions:create
  2. 运行迁移

    rake db:migrate
  3. 修改config/initializers/session_store.rb

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

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

完成这三个步骤后,请重新启动应用程序。Rails现在将使用会话表来存储会话数据,并且您将没有4kb的限制。


1
是有可能看到cookie来检查了这一点
erogol

只是好奇-这是每个会话或每个应用程序4kb的限制吗?
colllin

1
@colllin,按会话计算。
2013年

我需要active_record_store宝石吗?
Saad Masood 2013年

还是rails4的一部分
Saad Masood

78

要使:active_record_store功能在Rails 4/5中工作,必须将activerecord-session_store gem 添加到您的Gemfile

gem 'activerecord-session_store'

然后运行迁移生成器:

rails generate active_record:session_migration
rake db:migrate

最后在config/initializers/session_store.rb以下位置设置您的会话存储:

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

更新:

如果有人null value in column "session_id" violates not-null constraint在Rails 4中收到消息,那么github中有一个解决方法(未经测试)。您必须使用以下命令创建一个初始化程序ActiveRecord::SessionStore::Session.attr_accessible :data, :session_id


使用此gem时没有出现错误?我得到以下信息:ERROR: null value in column "session_id" violates not-null constraint
彼得

@Peter我没发生过,但是这里仍然是一个未解决的问题。我唯一的建议是在该问题上写评论以观看,直到有人修复为止。抱歉:/
Alter Lagos

@Peter我不确定是否为时已晚,但是无论如何请检查我的最新答案
Alter Lagos 2013年

2
运行“ rails generate active_record:session_migration”后,不要忘记运行:“ rake db:migrate”!
Patrice Gagnon 2014年

2
如果我不想在数据库中存储任何内容,该如何解决错误?我在ApplicationController中尝试了ActionDispatch :: Cookies :: CookieOverflow的result_from::with =>:render_404,但没有成功
nisevi 2015年

14

如果看到此消息,请检查您是否没有炸毁一些会话数据。就我而言,这是成千上万条相同的消息被注入到闪存消息中。只是说。

我要补充一点,如果您认为解决方案是使您的Cookie存储更大(其他大多数答案都针对此问题),那么最好重新考虑一下您实际在Cookie中放置的内容。如果您需要多个身份验证令牌,会话ID以及可能需要几个布局/跟踪cookie,那么您就生活在90年代。


1
我正在深度合并一些参数以保存状态!
Anwar

2
这也是我的错误原因。在Flash消息中放入太多数据。
knubie

10

在会话中存储模型对象不是一个好主意。

查看有关此主题的以下railscast:http ://railscasts.com/episodes/13-dangers-of-model-in-session?autoplay=true

最好将ID(在这种情况下为用户ID)存储在会话中。这样您就不会有这个问题。

(另请参见上方的Frederick Cheung评论)。


9

该错误消息清楚地表明Cookie存储区大小出现问题。

您的会话(默认情况下在Cookie中)需要移至Active Record存储或Memcache存储以解决此问题。

对于数据库会话:

config.action_controller.session_store = :active_record_store

您需要如下创建会话表

rake db:sessions:create
rake db:migrate

要么

对于Memcache会话:

config.action_controller.session_store = :mem_cache_store

另外,您需要设置内存缓存服务器并按以下方式进行配置:

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

6

该错误是因为您正在尝试序列化用户模型,当将对象存储在cookie中时,rails将使用Marshal.dump,由于用户记录中的所有内容,它会产生大量内容

与其session[:current_user] = user尝试仅存储用户ID 来存储实际用户记录,不如通过一种方法来从中查找用户,例如

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

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

1

我在运行规格时对我出现了此错误。将水豚从1.x更新到2.x之后。只是耙tmp:clear解决了它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.