Question

After upgrading to Rails 4.1.4 from Rails 3.2, accessing the application with an existing session (from the older Rails 3.2 version) causes an internal server error. backtrace:

JSON::ParserError - 795: unexpected token at {
I"session_id:ETI"%fa78a4ee07ac952c9b034ebc6199f30b;':
  /Users/.../.rvm/rubies/ruby-2.1.0/lib/ruby/2.1.0/json/common.rb:155:in `parse'
  actionpack (4.1.4) lib/action_dispatch/middleware/cookies.rb:388:in `load'
  actionpack (4.1.4) lib/action_dispatch/middleware/cookies.rb:428:in `deserialize'
  actionpack (4.1.4) lib/action_dispatch/middleware/cookies.rb:183:in `verify_and_upgrade_legacy_signed_message'
  actionpack (4.1.4) lib/action_dispatch/middleware/cookies.rb:550:in `[]'
  actionpack (4.1.4) lib/action_dispatch/middleware/session/cookie_store.rb:114:in `get_cookie'
  actionpack (4.1.4) lib/action_dispatch/middleware/session/cookie_store.rb:90:in `block in unpacked_cookie_data'
  actionpack (4.1.4) lib/action_dispatch/middleware/session/abstract_store.rb:51:in `stale_session_check!'
  actionpack (4.1.4) lib/action_dispatch/middleware/session/cookie_store.rb:89:in `unpacked_cookie_data'
  actionpack (4.1.4) lib/action_dispatch/middleware/session/cookie_store.rb:83:in `block in extract_session_id'
  actionpack (4.1.4) lib/action_dispatch/middleware/session/abstract_store.rb:51:in `stale_session_check!'
  actionpack (4.1.4) lib/action_dispatch/middleware/session/cookie_store.rb:82:in `extract_session_id'
  actionpack (4.1.4) lib/action_dispatch/request/session.rb:49:in `block in []'
  actionpack (4.1.4) lib/action_dispatch/request/session.rb:48:in `[]'
  actionpack (4.1.4) lib/action_dispatch/request/session.rb:70:in `id'
  rack (1.5.2) lib/rack/session/abstract/id.rb:282:in `current_session_id'
  rack (1.5.2) lib/rack/session/abstract/id.rb:288:in `session_exists?'
  actionpack (4.1.4) lib/action_dispatch/request/session.rb:152:in `exists?'
  actionpack (4.1.4) lib/action_dispatch/request/session.rb:172:in `load_for_read!'
  actionpack (4.1.4) lib/action_dispatch/request/session.rb:89:in `[]'
  warden (1.2.3) lib/warden/session_serializer.rb:30:in `fetch'
  warden (1.2.3) lib/warden/proxy.rb:212:in `user'
  warden (1.2.3) lib/warden/proxy.rb:318:in `_perform_authentication'
  warden (1.2.3) lib/warden/proxy.rb:104:in `authenticate'
  warden (1.2.3) lib/warden/proxy.rb:114:in `authenticate?'
  devise (3.2.4) lib/devise/rails/routes.rb:460:in `block in constraints_for'
  actionpack (4.1.4) lib/action_dispatch/routing/mapper.rb:38:in `block in matches?'
  actionpack (4.1.4) lib/action_dispatch/routing/mapper.rb:36:in `matches?'
  actionpack (4.1.4) lib/action_dispatch/routing/mapper.rb:45:in `call'
  actionpack (4.1.4) lib/action_dispatch/journey/router.rb:71:in `block in call'
  actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in `call'
  actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:678:in `call'
  ...

I tried to change the session cookie key name, but it seems to be stuck on session_id.

# initializers/session_store.rb
MyApp::Application.config.session_store :cookie_store, key: 'myapp_session'

Please help! A great solution would also be to delete all session cookies before they hit the rails middleware, but i have no idea how to do that..

Was it helpful?

Solution

Found the answer here: https://github.com/rails/rails/issues/15111

My settings had

# initializers/cookie_serializer.rb
Rails.application.config.action_dispatch.cookies_serializer = :json

I changed it to

Rails.application.config.action_dispatch.cookies_serializer = :hybrid

And that did the trick

OTHER TIPS

If you're comfortable with changing your secret key, then it will solve the problem, and I can confirm that people with old cookies will not encounter a 500 error.

Run rake secret to generate a new secret.

If you've implemented config/secrets.yml, put the new secret in there. Otherwise, if you still have your secret in config/initializers/secret_token.rb, put it in there.

Leave your config/initializers/session_store.rb file alone -- you don't need to change it.

In config/initializers/cookie_store.rb, change it to :json:

# Be sure to restart your server when you modify this file.

Rails.application.config.action_dispatch.cookies_serializer = :json

I can confirm that this works, even when your browser is storing an old session cookie. By changing the secret, when someone with an old session cookie visits your site, the server simply ignores the old session state and creates a new session. No 500 error.

I just had the same problem and used the answer here and all was fixed. After reading the comments though I found that just changing the secret also fixed the problem, as it should I suppose.

I think changing the secret is a better solution to the problem than switching to :hybrid like @Thibaut Barrère stated in the comments

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top