Cookie tràn trong ứng dụng rails?


106

ActionDispatch :: Cookies :: CookieOverflow trong UsersController # create

Tôi gặp lỗi này khi cố gắng mở trang. Tôi không biết làm thế nào để gỡ lỗi này. Bạn có bất kỳ đề nghị cho vấn đề này?

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
lỗi này xảy ra khi bạn có một dữ liệu / đối tượng lớn trong phiên. Bạn có thể chia sẻ mã để tạo hành động trong bộ điều khiển không?
Naren Sisodiya


3
Mặc dù câu trả lời về việc thay đổi lưu trữ phiên của bạn là đúng, nhưng tôi sẽ đặt câu hỏi tại sao bạn muốn lưu trữ toàn bộ người dùng trong phiên. Nếu bạn phải lưu trữ thứ gì đó, hãy lưu trữ user_id (mặc dù cái đó đã có trong cookie của bạn)
Frederick Cheung

Chỉ cần truy cập kho lưu trữ bộ nhớ cache của trình duyệt và xóa cookie thuộc về url trang web cụ thể đó. đối với tôi nó chủ yếu xảy ra trong localhost.
ben

Tôi đã tạo một mô hình người dùng với Devisevà tôi chưa khởi động lại máy chủ phát triển của mình sau khi chạy quá trình di chuyển. Sau khi tôi làm vậy, lỗi đã dừng lại.
wuliwong

Câu trả lời:


159

Bạn có giới hạn 4kb về những gì bạn có thể lưu trữ trong cookie và khi Rails chuyển đổi đối tượng của bạn thành văn bản để ghi vào cookie thì nó có thể lớn hơn giới hạn đó.

Ruby on Rails ActionDispatch::Cookies::CookieOverflowlỗi

Bằng cách đó, CookieOverflowlỗi này xảy ra.

Cách dễ nhất để giải quyết vấn đề này là bạn cần thay đổi session_store của mình và không sử dụng cookie_store. Bạn có thể sử dụng active_record_storeví dụ.

Đây là các bước

  1. Tạo một di chuyển tạo bảng phiên

    rake db:sessions:create
  2. Chạy quá trình di chuyển

    rake db:migrate
  3. Sửa đổi config/initializers/session_store.rbtừ

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

    đến

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

Khi bạn đã thực hiện xong ba bước, hãy khởi động lại ứng dụng của bạn. Rails bây giờ sẽ sử dụng bảng phiên để lưu trữ dữ liệu phiên và bạn sẽ không bị giới hạn 4kb.


1
là nó có thể để xem cookie mà xem này
erogol

chỉ tò mò - đây là giới hạn 4kb mỗi phiên hay mỗi ứng dụng?
colllin

1
@colllin, đó là mỗi phiên.
Alex D

tôi có cần active_record_stoređá quý không?
Saad Masood

hoặc là nó là một phần của rails4
Saad Masood

78

Để làm cho :active_record_storechức năng hoạt động trong Rails 4/5, bạn phải thêm gem activerecord-session_store vào Gemfile:

gem 'activerecord-session_store'

sau đó chạy trình tạo di chuyển:

rails generate active_record:session_migration
rake db:migrate

Và cuối cùng đặt cửa hàng phiên của bạn trong config/initializers/session_store.rb:

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

CẬP NHẬT:

Nếu bất kỳ ai đang nhận được null value in column "session_id" violates not-null constrainttin nhắn trong rails 4, có một giải pháp trong github (không được thử nghiệm). Bạn phải tạo trình khởi tạo vớiActiveRecord::SessionStore::Session.attr_accessible :data, :session_id


Bạn không gặp lỗi khi sử dụng viên ngọc này? Tôi nhận được những điều sau:ERROR: null value in column "session_id" violates not-null constraint
Peter

@Peter Nó không xảy ra với tôi, nhưng ở đây vẫn xuất hiện như một vấn đề mở. Lời khuyên duy nhất của tôi là viết một bình luận trong vấn đề đó để xem nó cho đến khi ai đó sửa chữa. Xin lỗi: /
Alter Lagos,

@Peter Tôi không chắc liệu có quá muộn hay không, nhưng dù sao hãy kiểm tra câu trả lời đã cập nhật của tôi
Alter Lagos

2
Sau khi chạy "rails create active_record: session_migration", đừng quên chạy: "rake db: migrate"!
Patrice Gagnon

2
Điều gì sẽ xảy ra nếu tôi không muốn lưu trữ bất kỳ thứ gì trong DB làm cách nào để khắc phục lỗi? Tôi cố gắng rescue_from ActionDispatch :: Cookies :: CookieOverflow,: với =>: render_404 trong ApplicationController nhưng nó đã không làm việc
nisevi

14

Nếu bạn thấy thông báo này, hãy kiểm tra để đảm bảo rằng bạn không làm hỏng một số dữ liệu phiên. Trong trường hợp của tôi, đó là hàng ngàn thông điệp giống nhau được bơm vào tin nhắn flash. Chỉ nói.

Tôi sẽ nói thêm rằng nếu bạn nghĩ giải pháp là làm cho kho lưu trữ cookie của bạn lớn hơn (như hầu hết các địa chỉ câu trả lời khác), có lẽ bạn nên suy nghĩ lại những gì bạn thực sự đưa vào cookie. Nếu bạn cần nhiều hơn một vài mã thông báo xác thực, ID phiên và có thể một vài cookie bố cục / theo dõi, bạn đang sống ở những năm 90.


1
Tôi đã hợp nhất sâu một số tham số để tiết kiệm trạng thái!
Anwar

2
Đây là nguyên nhân gây ra lỗi cho tôi. Đưa quá nhiều dữ liệu vào tin nhắn flash.
knubie

10

Lưu trữ một đối tượng mô hình trong phiên không phải là một ý kiến ​​hay.

Xem railscast về chủ đề này: http://railscasts.com/episodes/13-dangers-of-model-in-session?autoplay=true

Cách tốt hơn là lưu trữ id (id của người dùng trong trường hợp này) bên trong phiên. Sau đó, bạn sẽ không gặp vấn đề này.

(Xem thêm bình luận của Frederick Cheung ở trên).


9

thông báo lỗi chỉ ra rõ ràng vấn đề với kích thước cửa hàng cookie bị tràn.

Các phiên của bạn (theo mặc định trong cookie) cần được chuyển đến Kho lưu trữ bản ghi hoạt động hoặc lưu trữ memcache để khắc phục sự cố này.

Đối với phiên dựa trên dữ liệu:

config.action_controller.session_store = :active_record_store

Bạn cần tạo bảng phiên như bên dưới

rake db:sessions:create
rake db:migrate

HOẶC LÀ

Đối với các phiên Memcache:

config.action_controller.session_store = :mem_cache_store

Ngoài ra, bạn cần thiết lập một máy chủ bộ nhớ đệm ghi nhớ và cấu hình nó như bên dưới:

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

6

Lỗi đó là do bạn đang cố gắng tuần tự hóa mô hình người dùng Khi lưu trữ một đối tượng trong cookie, rails sẽ sử dụng Marshal.dump có thể tạo ra một lượng lớn nội dung vì đó là mọi thứ trong hồ sơ người dùng

Thay vì lưu trữ hồ sơ người dùng thực tế, session[:current_user] = userhãy thử chỉ lưu trữ ID của người dùng, sau đó có một phương pháp, một phương pháp để tra cứu người dùng từ đó, ví dụ:

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

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

1

Lỗi này xuất hiện cho tôi khi tôi đang chạy một thông số kỹ thuật. Sau khi cập nhật Capybara từ 1.x lên 2.x. Chỉ cần cào tmp: rõ ràng đã giải quyết nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.