Action Pack: Cookie store sessions = blow up app in 2.0?

DHH writes in his new 2.0 update over view the following:

The default session store in Rails 2.0 is now a cookie-based one. That means sessions are no longer stored on the file system or in the database, but kept by the client in a hashed form that can't be forged. This makes it not only a lot faster than traditional session stores, but also makes it zero maintenance. There's no cron job needed to clear out the sessions and your server won't crash because you forgot and suddenly had 500K files in tmp/session.

When I go into my environment.rb file and comment out the;

config.action_controller.session_store = :active_record_store

my application goes completely DEAD. I do have a sessions table and DID have it keeping the session in the database before. Can anyone suggest how I should proceed for my new Rails 2.0 application. Thank you, Kathleen

DHH writes in his new 2.0 update over view the following:

The default session store in Rails 2.0 is now a cookie-based one. That means sessions are no longer stored on the file system or in the database, but kept by the client in a hashed form that can't be forged. This makes it not only a lot faster than traditional session stores, but also makes it zero maintenance. There's no cron job needed to clear out the sessions and your server won't crash because you forgot and suddenly had 500K files in tmp/session.

When I go into my environment.rb file and comment out the;

config.action_controller.session_store = :active_record_store

my application goes completely DEAD. I do have a sessions table and DID have it keeping the session in the database before.

Have you defined a secret to use for the cookies (I expect there's a
message in your logs about it) ? You set the secret in environment.rb config.action_controller.session = {     :session_key => '_empty_app_session',     :secret => 'your secret here'   }

If you generate a new app rails will create a nice long safe secret
for you. You can run rake secret to get rails to generate you a nice secret.

Fred

In addition it is a good idea to change the name of the cookie.

Otherwise the first time a user with an old session hits the site CGI::Session::CookieStore::TamperedWithCookie is raised because the cookie value looks invalid. A session ID was gotten, but now Rails expects <data>--<digest> and ensures nobody has tampered with the cookie.

-- fxn

You mean new session_key, right?

Hi, I ran into (probably) the same error as Kathleen did tonight. I'm using the default environment.rb, but changing the session_store to use AR as a session_store, and I get an error:

"ActionController::InvalidAuthenticityToken in Products#new No :secret given to the #protect_from_forgery call."

I've tried to reproduce it in the simplest manner I can think of. I'm running Rails 2.0.2 (on Leopard, if it makes any difference). Here's what I do to reproduce this error:

rails newapp cd newapp/ script/scaffold some_model name:string rake db:sessions:create vim config/environment.rb # (uncommenting config.action_controller.session_store = :active_record_store, nothing else. :secret is set a few lines above) rake db:migrate script/server

Everything seems just fine up till now. No errors on the rake tasks or anything.

I clean out all cookies from localhost in Safari, and then I get visit http://localhost:3000/some_model/new and get the error. (For some reason, http://localhost:3000/some_models does not produce the error.) I've tried the above, using mysql as my database instead of sqlite (because I'm more comfortable on the mysql prompt), and had a look. Everything is there. The sessions table does indeed have a row after I've visited the url. The browser has a new cookie set from localhost. But still I get the ActionController::InvalidAuthenticityToken error.

Have I done something weird? Here's an excerpt from my config/environment.rb:

  # Your secret key for verifying cookie session data integrity.   # If you change this key, all old sessions will become invalid!   # Make sure the secret is at least 30 characters and all random,   # no regular words or you'll be exposed to dictionary attacks.   config.action_controller.session = {     :session_key => '_testapp_session',     :secret => '0a3cae420e2e43d216f641e7c84958c357eec74593bee85cb3f9a46bb9fc7f8ebe52d9f8ac5d3d429a678ce91f46336fb04e91a4f9054c164f8f258932763e59'   }

  # Use the database for sessions instead of the cookie-based default,   # which shouldn't be used to store highly confidential information   # (create the session table with 'rake db:sessions:create')   config.action_controller.session_store = :active_record_store

If it's a bug in Rails 2.0.2, I hope this helps to confirm it.

- Martin

That's it.

-- fxn

"ActionController::InvalidAuthenticityToken in Products#new No :secret given to the #protect_from_forgery call."

That's the error message. Check your application.rb file It generates a secret, but comments it out because it can use the CookieSessionStore secret.

Thank you, that solved the problem. I thought it used the :secret in config.action_controller.session... Maybe I'll get around to submitting a patch on the comments in environment.rb, giving a hint about the :secret in application.rb in the comment for config.action_controller.session_store = :active_record_store. :slight_smile:

- Martin

That worked for me as well.

I am just starting to learn Ruby on Rails, I will be really grateful if someone can tell me what do I have wrong in my files because it gives me the next error: " ActionController::InvalidAuthenticityToken in Store#index"

The content of my files are: Environment.rb: " # Be sure to restart your server when you modify this file

# Uncomment below to force Rails into production mode when # you don't control web/app server and can't set it the proper way # ENV['RAILS_ENV'] ||= 'production'

# Specifies gem version of Rails to use when vendor/rails is not present RAILS_GEM_VERSION = '2.0.2' unless defined? RAILS_GEM_VERSION

# Bootstrap the Rails environment, frameworks, and default configuration require File.join(File.dirname(__FILE__), 'boot')

Rails::Initializer.run do |config|   # Settings in config/environments/* take precedence over those specified here.   # Application configuration should go into files in config/ initializers   # -- all .rb files in that directory are automatically loaded.   # See Rails::Configuration for more options.

  # Skip frameworks you're not going to use (only works if using vendor/rails).   # To use Rails without a database, you must remove the Active Record framework   # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]

  # Only load the plugins named here, in the order given. By default, all plugins   # in vendor/plugins are loaded in alphabetical order.   # :all can be used as a placeholder for all plugins not explicitly named   # config.plugins = [ :exception_notification, :ssl_requirement, :all ]

  # Add additional load paths for your own custom dirs   # config.load_paths += %W( #{RAILS_ROOT}/extras )

  # Force all environments to use the same logger level   # (by default production uses :info, the others :debug)   # config.log_level = :debug

  # Your secret key for verifying cookie session data integrity.   # If you change this key, all old sessions will become invalid!   # Make sure the secret is at least 30 characters and all random,   # no regular words or you'll be exposed to dictionary attacks.   config.action_controller.session = {     :session_key => '_depot_session',     :secret => '2eae1bebb00c0983fdf1c7a908cc59dd992d3096449a07e432589e604ae164081eb4a1ce9e387c925fead854e6c586e17b2b56d68cf0b3dec4a8b7ff32aabc9e'   }

  # Use the database for sessions instead of the cookie-based default,   # which shouldn't be used to store highly confidential information   # (create the session table with 'rake db:sessions:create')   config.action_controller.session_store = :active_record_store

  # Use SQL instead of Active Record's schema dumper when creating the test database.   # This is necessary if your schema can't be completely dumped by the schema dumper,   # like if you have constraints or database-specific column types   # config.active_record.schema_format = :sql

  # Activate observers that should always be running   # config.active_record.observers = :cacher, :garbage_collector

  # Make Active Record use UTC-base instead of local time   # config.active_record.default_timezone = :utc end"

application.rb: "# Filters added to this controller apply to all controllers in the application. # Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base # helper :all # include all helpers, all the time

  # See ActionController::RequestForgeryProtection for details   # Uncomment the :secret if you're not using the cookie session store

  # Pick a unique cookie name to distinguish our session data from others' session :session_key => '_depot_session' protect_from_forgery :secret => '2eae1bebb00c0983fdf1c7a908cc59dd992d3096449a07e432589e604ae164081eb4a1ce9e387c925fead854e6c586e17b2b56d68cf0b3dec4a8b7ff32aabc9e'

end"

Thanks in advance. Belén

How are you creating your forms? If you're not using the rails helpers, you'll need to use token_tag to add the authenticity token.

Fred

Wha do you mean with the forms?

Wha do you mean with the forms?

if you're just writing

<form ...>

</form> Then the token won't be magically added for you if you are using form_for, form_tag etc... then it will

Fred

I have solved the problem! Thanks for your help!!! I was not writing <form>. Belénn