You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails应用出现ActionDispatch::Cookies::CookieOverflow错误求助

问题:ActionDispatch::Cookies::CookieOverflow 错误排查与解决

问题描述

我在Stack Overflow上看过多个相关帖子,但没法套用解决方案。我的Rails应用出现ActionDispatch::Cookies::CookieOverflow错误(来自sentry.io的错误标题)。我没在应用里自定义使用Cookie,但怀疑两个点:

  • 认证gem Devise在使用Cookie,但搞不清为什么会触发溢出;
  • 生成PDF的wkhtml工具可能涉及Cookie,但具体情况不明确。

这个错误是客户触发的,我自己复现不了,求提供可执行的复现步骤和解决方案。

Sentry堆栈跟踪

ActionDispatch::Cookies::CookieOverflow

actionpack (6.0.3.6) lib/action_dispatch/middleware/cookies.rb in commit at line 637
actionpack (6.0.3.6) lib/action_dispatch/middleware/cookies.rb in []= at line 472
actionpack (6.0.3.6) lib/action_dispatch/middleware/session/cookie_store.rb in set_cookie at line 110
rack (2.2.3) lib/rack/session/abstract/id.rb in commit_session at line 403
rack (2.2.3) lib/rack/session/abstract/id.rb in context at line 268
rack (2.2.3) lib/rack/session/abstract/id.rb in call at line 260
actionpack (6.0.3.6) lib/action_dispatch/middleware/cookies.rb in call at line 648
actionpack (6.0.3.6) lib/action_dispatch/middleware/callbacks.rb in block in call at line 27
activesupport (6.0.3.6) lib/active_support/callbacks.rb in run_callbacks at line 101
actionpack (6.0.3.6) lib/action_dispatch/middleware/callbacks.rb in call at line 26
actionpack (6.0.3.6) lib/action_dispatch/middleware/actionable_exceptions.rb in call at line 18
actionpack (6.0.3.6) lib/action_dispatch/middleware/debug_exceptions.rb in call at line 32
actionpack (6.0.3.6) lib/action_dispatch/middleware/show_exceptions.rb in call at line 33
railties (6.0.3.6) lib/rails/rack/logger.rb in call_app at line 37
railties (6.0.3.6) lib/rails/rack/logger.rb in block in call at line 26
activesupport (6.0.3.6) lib/active_support/tagged_logging.rb in block in tagged at line 80
activesupport (6.0.3.6) lib/active_support/tagged_logging.rb in tagged at line 28
activesupport (6.0.3.6) lib/active_support/tagged_logging.rb in tagged at line 80
railties (6.0.3.6) lib/rails/rack/logger.rb in call at line 26
actionpack (6.0.3.6) lib/action_dispatch/middleware/remote_ip.rb in call at line 81
actionpack (6.0.3.6) lib/action_dispatch/middleware/request_id.rb in call at line 27
rack (2.2.3) lib/rack/method_override.rb in call at line 24
rack (2.2.3) lib/rack/runtime.rb in call at line 22
activesupport (6.0.3.6) lib/active_support/cache/strategy/local_cache_middleware.rb in call at line 29
actionpack (6.0.3.6) lib/action_dispatch/middleware/executor.rb in call at line 14
rack (2.2.3) lib/rack/sendfile.rb in call at line 110
actionpack (6.0.3.6) lib/action_dispatch/middleware/host_authorization.rb in call at line 76
sentry-ruby-core (4.3.2) lib/sentry/rack/capture_exceptions.rb in block in call at line 23
sentry-ruby-core (4.3.2) lib/sentry/hub.rb in with_scope at line 52
sentry-ruby-core (4.3.2) lib/sentry-ruby.rb in with_scope at line 147
sentry-ruby-core (4.3.2) lib/sentry/rack/capture_exceptions.rb in call at line 14
railties (6.0.3.6) lib/rails/engine.rb in call at line 527
/usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb in process_request at line 107

/usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler/thread_handler.rb in accept_and_process_next_request at line 149

/usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler/thread_handler.rb in main_loop at line 110

/usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler.rb in block (3 levels) in start_threads at line 419

/usr/lib/ruby/vendor_ruby/phusion_passenger/utils.rb in block in create_thread_and_abort_on_exception at line 113

复现步骤

  • 模拟大体积Session数据:在本地开发环境往Devise的session或Rails全局session里存大量数据(比如带复杂关联的用户模型、大段文本),然后触发PDF生成操作,确保wkhtml工具携带当前session。
  • 触发Cookie上限:浏览器单条Cookie上限一般是4KB,手动构造超出该大小的session数据(比如序列化包含大量关联数据的用户对象),执行用户触发错误的相同操作路径(比如登录后生成特定PDF)。
  • 多场景组合测试:登录关联数据多的用户账号,连续多次执行PDF生成操作,观察session是否被持续追加数据。

解决方案

1. 切换Session存储方式

Rails默认用CookieStore,超过4KB就会报错,换成服务器端存储:

  • RedisStore:
    安装依赖gem:
    gem install redis redis-rails
    
    修改config/initializers/session_store.rb:
    Rails.application.config.session_store :redis_store, {
      servers: ["redis://localhost:6379/0/session"],
      expire_after: 1.day,
      key: "_your_app_session"
    }
    
  • ActiveRecordStore:
    生成session表:
    rails generate session_migration
    rails db:migrate
    
    修改config/initializers/session_store.rb:
    Rails.application.config.session_store :active_record_store, key: "_your_app_session"
    

2. 清理Devise Session冗余数据

  • 自定义Devise的session序列化,只存必要字段:
    在用户模型里添加:
    def serialize_into_session
      [id, email] # 只存ID和必要标识,不存整个用户对象
    end
    
  • 检查是否有其他代码往session里写大体积数据,删掉不必要的存储内容。

3. 隔离wkhtml的Cookie使用

  • 生成PDF时,避免传递完整用户session,只传必要的认证令牌:
    # 生成PDF时手动构造请求,仅携带认证令牌
    pdf_url = url_for(controller: "documents", action: "show", token: current_user.authentication_token)
    wkhtmltopdf(pdf_url, output_path)
    
  • 确保wkhtml工具不会往session里写入额外数据。

4. 监控Session大小

  • 在中间件里添加session大小监控,提前预警:
    # config/initializers/session_monitor.rb
    class SessionSizeMonitor
      def initialize(app)
        @app = app
      end
    
      def call(env)
        session = env['rack.session']
        if session
          size = Marshal.dump(session).size
          Rails.logger.warn "Session size exceeds 3KB: #{size} bytes" if size > 3072
        end
        @app.call(env)
      end
    end
    
    Rails.application.config.middleware.use SessionSizeMonitor
    

内容的提问来源于stack exchange,提问作者Julian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:15:28