Переповнення файлів cookie в додатку для рейків?


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
ця помилка виникає, коли у вас у сесії є великі дані / об'єкт. Чи можете ви поділитися кодом для створення дії в контролері?
Нарен Сисодія


3
Хоча відповіді про зміну магазину сесій є правильними, я б запитав, чому ви хочете зберігати всього користувача в сесії. Якщо вам потрібно щось зберігати, зберігайте user_id (хоча це вже є у вашому файлі cookie)
Frederick Cheung

Просто перейдіть до магазину кешу браузера та очистіть файли cookie, що належать до конкретної URL-адреси веб-сайту. для мене це відбувається здебільшого у localhost.
бен

Я створив модель користувача, за допомогою Deviseякої не запустив сервер розробки після запуску міграцій. Як тільки я це зробив, помилка припинилася.
wuliwong

Відповіді:


159

У вас обмеження 4 кб щодо того, що ви можете зберігати у файлі cookie, і коли Rails перетворює ваш об’єкт у текст для запису на файл cookie, він, ймовірно, перевищує межу.

ActionDispatch::Cookies::CookieOverflowПомилка Ruby on Rails

Так 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
чи можна побачити це печиво, щоб перевірити це
erogol

просто цікаво - це обмеження 4 кб на сеанс чи на додаток?
коллін

1
@colllin, це за сеанс.
Алекс Д

мені потрібен active_record_storeдорогоцінний камінь?
Саад Масуд

або це частина рейок4
Саад Масуд

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повідомлення в рейки 4, у Github є вирішення (не перевірено). Потрібно створити ініціалізатор за допомогоюActiveRecord::SessionStore::Session.attr_accessible :data, :session_id


Ви не отримали помилку під час використання цього дорогоцінного каміння? Я отримую наступне:ERROR: null value in column "session_id" violates not-null constraint
Пітер

@Peter Це не сталося зі мною, але тут все ще з'являється як відкрите питання. Моя єдина порада - написати коментар до цього питання, щоб переглянути його, поки хтось не виправить. Вибачте: /
Alter Lagos

@Peter Я не впевнений, чи не пізно, але все одно перевірити мою оновлену відповідь
Alter Lagos

2
Після запуску "рейки генерують active_record: session_migration", не забудьте запустити: "rake db: migrate"!
Патріс Ганьон

2
що робити, якщо я не хочу зберігати нічого в БД, як я можу врятувати помилку? Я спробував spas_from ActionDispatch :: Cookies :: CookieOverflow,: with =>: render_404 в ApplicationController, але це не спрацювало
nisevi

14

Якщо ви бачите це, переконайтеся, що ви не показуєте деякі дані сеансу. У моєму випадку це було одне і те ж повідомлення, прокачане у спалах. Просто кажу.

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


1
Я глибоко зливав деякі парами, щоб зберегти стан!
Анвар

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 рейки використовуватимуть 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

1

Ця помилка з’явилася для мене, коли я запускав специфікації. Після оновлення Capybara з 1.x до 2.x. Просто граблі tmp: ясно вирішили.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.