Переполнение cookie в приложении rails?

106

ActionDispatch :: Cookies :: CookieOverflow в UsersController # create

У меня эта ошибка возникает при попытке открыть страницу. Я не знаю, как отладить эту ошибку. У вас есть предложения по этой проблеме?

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
эта ошибка возникает, когда у вас есть большие данные / объект в сеансе. Можете ли вы поделиться кодом для создания действия в контроллере?
Нарен Сисодия
1
Дубликат stackoverflow.com/questions/4782611/… ?
iblue
3
Хотя ответы об изменении хранилища сеансов верны, я бы спросил, почему вы хотите сохранить всего пользователя в сеансе. Если вам нужно что-то сохранить, сохраните user_id (хотя он уже находится в вашем файле cookie)
Фредерик Чунг,
Просто перейдите в хранилище кеша браузера и очистите файлы cookie, принадлежащие этому URL-адресу веб-сайта. для меня это происходит в основном в localhost.
Бен
Я создал модель пользователя Deviseи не перезапускал сервер разработки после выполнения миграции. Как только я это сделал, ошибка прекратилась.
wuliwong

Ответы:

159

У вас есть ограничение в 4 КБ на то, что вы можете хранить в cookie, и когда Rails конвертирует ваш объект в текст для записи в cookie, он, вероятно, превышает этот предел.

Рубин на рельсах 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 теперь будет использовать таблицу сеансов для хранения данных сеанса, и у вас не будет ограничения в 4 КБ.

AMIC MING
источник
1
можно ли увидеть этот файл cookie, чтобы проверить это
erogol
просто любопытно - это лимит 4 КБ на сеанс или на приложение?
colllin 05
1
@colllin, это за сеанс.
Alex D
мне нужен active_record_storeдрагоценный камень?
Саад Масуд
или это часть rails4
Саад Масуд
78

Чтобы :active_record_storeфункциональность работала в Rails 4/5, вы должны добавить гем activerecord-session_store в свой 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

Alter Lagos
источник
Вы не получали ошибку при использовании этого камня? Получаю следующее:ERROR: null value in column "session_id" violates not-null constraint
Питер
@Peter Это не случилось со мной, но здесь все еще остается открытым вопрос. Мой единственный совет - написать комментарий в этом выпуске, чтобы смотреть его, пока кто-нибудь не исправит. Извините: /
Alter Lagos
@Peter Я не уверен, что уже слишком поздно, но все равно проверьте мой обновленный ответ
Alter Lagos
2
После запуска «rails generate active_record: session_migration» не забудьте запустить: «rake db: migrate»!
Патрис Ганьон
2
что, если я не хочу ничего хранить в БД, как я могу спасти ошибку? Я попробовал rescue_from ActionDispatch :: Cookies :: CookieOverflow,: with =>: render_404 в ApplicationController, но это не сработало
nisevi
14

Если вы видите это, убедитесь, что вы не увеличиваете данные сеанса. В моем случае это были тысячи одинаковых сообщений, закачанных во флеш-сообщение. Просто говорю.

Я добавлю, что если вы думаете, что решение состоит в том, чтобы увеличить хранилище файлов cookie (как и большинство других ответов), вам, вероятно, лучше переосмыслить, что вы фактически вставляете в файлы cookie. Если вам нужно более пары токенов аутентификации, идентификаторов сеансов и, возможно, несколько файлов cookie макета / отслеживания, вы живете в 90-х годах.

Дэвид Хемпи
источник
1
Я глубоко объединял некоторые параметры, чтобы сохранить состояние!
Anwar
2
Это было причиной ошибки и для меня. Слишком много данных во флэш-сообщении.
Knubie
10

Не рекомендуется хранить объект модели в сеансе.

Посмотрите этот выпуск по этой теме: http://railscasts.com/episodes/13-dangers-of-model-in-session?autoplay=true

Лучше хранить идентификатор (в данном случае идентификатор пользователя) внутри сеанса. Тогда у вас не будет этой проблемы.

(См. Также комментарий Фредерика Ченга выше).

Зак Сюй
источник
9

сообщение об ошибке ясно указывает на проблему с переполнением размера хранилища файлов cookie.

Ваши сеансы (по умолчанию в файлах cookie) необходимо переместить в хранилище активных записей или хранилище кэша памяти, чтобы решить эту проблему.

Для сеансов на основе данных:

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попробуйте просто сохранить идентификатор пользователя, а затем используйте метод, чтобы найти пользователя из этого, например

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

def current_user
  @current_user ||= User.find(session[:current_user_id])
end
Cianmce
источник
1

Эта ошибка появилась у меня, когда я запускал спецификации. После обновления Capybara с 1.x до 2.x. Просто грабли tmp: clear решил это.

Artur79
источник