Rails 4 upgrade JSON::ParseError for old sessions

梦想与她 提交于 2019-12-09 15:06:36

问题


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..


回答1:


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




回答2:


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.




回答3:


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



来源:https://stackoverflow.com/questions/25031985/rails-4-upgrade-jsonparseerror-for-old-sessions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!