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