【问题标题】:Cookie overflow in rails application?Rails应用程序中的Cookie溢出?
【发布时间】:2012-02-27 23:06:04
【问题描述】:

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

【问题讨论】:

  • 当您在会话中有大量数据/对象时会出现此错误。可以分享一下控制器中创建动作的代码吗?
  • 虽然关于更改会话存储的答案是正确的,但我会质疑为什么要将整个用户存储在会话中。如果您必须存储某些内容,请存储 user_id(尽管它已经在您的 cookie 中)
  • 只需转到浏览器缓存存储,并清除属于该特定网站 url 的 cookie。对我来说,它主要发生在本地主机中。
  • 我使用Devise 创建了一个用户模型,并且在运行迁移后我没有重新启动我的开发服务器。一旦我这样做了,错误就停止了。

标签: ruby-on-rails


【解决方案1】:

您可以在 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 的限制。

【讨论】:

  • 是否可以查看该 cookie 来检查这一点
  • 只是好奇 - 这是每个会话或每个应用程序的 4kb 限制吗?
  • @colllin,每次会话。
  • 我需要active_record_store gem吗?
  • 或者它是 rails4 的一部分
【解决方案2】:

要使: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'

更新:

如果有人在 rails 4 中收到 null value in column "session_id" violates not-null constraint 消息,则有 workaround in github(未测试)。你必须用ActiveRecord::SessionStore::Session.attr_accessible :data, :session_id创建一个初始化器

【讨论】:

  • 您在使用这个 gem 时没有收到错误消息吗?我得到以下信息:ERROR: null value in column "session_id" violates not-null constraint
  • @Peter 这并没有发生在我身上,但here 仍然显示为一个未解决的问题。我唯一的建议是在该问题上写评论以观察它,直到有人修复为止。对不起:/
  • @Peter 我不确定是否为时已晚,但无论如何请检查我的更新答案
  • 运行“rails generate active_record:session_migration”后不要忘记运行:“rake db:migrate”!
  • 如果我不想在数据库中存储任何内容,我该如何挽救错误?我在 ApplicationController 中尝试了 rescue_from ActionDispatch::Cookies::CookieOverflow, :with => :render_404 但它没有用
【解决方案3】:

如果您看到这种情况,请检查您是否没有破坏某些会话数据。在我的例子中,有数千条相同的消息被注入到 flash 消息中。只是说说而已。

我要补充一点,如果您认为解决方案是让您的 cookie 存储更大(正如大多数其他答案所指出的那样),那么您最好重新考虑一下您实际放入 cookie 中的内容。如果您需要多个身份验证令牌、会话 ID 以及一些布局/跟踪 cookie,那么您生活在 90 年代。

【讨论】:

  • 我正在深度合并一些参数以保存状态!
  • 这也是我出错的原因。将太多数据放入 Flash 消息中。
  • 是的,我在实施 OmniAuth-Keycloak 策略时遇到了这个问题。 Keycloak 提供了很多信息,包括用户的访问列表。只有少数与存储为 cookie 相关...
  • 黄金!这是一个 Flash 消息问题。
【解决方案4】:

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

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

在会话中存储 id(本例中为用户的 id)是一种更好的做法。 那你就不会有这个问题了。

(另请参阅上面的 Frederick Cheung 评论)。

【讨论】:

    【解决方案5】:

    错误消息清楚地表明 cookie 存储大小溢出的问题。

    您的会话(默认在 cookie 中)需要移动到活动记录 store 或 memcache store 来解决这个问题。

    对于数据库会话:

    config.action_controller.session_store = :active_record_store
    

    您需要如下创建会话表

    rake db:sessions:create
    rake db:migrate
    

    对于 Memcache 会话:

    config.action_controller.session_store = :mem_cache_store
    

    另外你需要设置一个mem缓存服务器并配置如下:

    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
      

      【讨论】:

        【解决方案7】:

        我在运行规范时出现了这个错误。在将 Capybara 从 1.x 更新到 2.x 之后。 只需 rake tmp:clear 即可解决。

        【讨论】:

          【解决方案8】:

          我的问题是因为代码

          rescue StandardError => e
            flash[:error] = "Error was #{error.message}"
          end
          

          error.message 太大了

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-05-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-15
            • 1970-01-01
            • 2016-06-13
            相关资源
            最近更新 更多