Ruby on rails 4 旧会话的Rails 4升级JSON::ParseError

Ruby on rails 4 旧会话的Rails 4升级JSON::ParseError,ruby-on-rails-4,session-cookies,ruby-on-rails-4.1,Ruby On Rails 4,Session Cookies,Ruby On Rails 4.1,从Rails 3.2升级到Rails 4.1.4后,使用现有会话(从较旧的Rails 3.2版本)访问应用程序会导致内部服务器错误。回溯: 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

从Rails 3.2升级到Rails 4.1.4后,使用现有会话(从较旧的Rails 3.2版本)访问应用程序会导致内部服务器错误。回溯:

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'
  ...
我试图更改会话cookie密钥名称,但它似乎卡在
session\u id

# initializers/session_store.rb
MyApp::Application.config.session_store :cookie_store, key: 'myapp_session'
请帮忙!一个很好的解决方案是在所有会话cookie进入rails中间件之前删除它们,但我不知道如何做到这一点。

在这里找到了答案:

我的设置有

# initializers/cookie_serializer.rb
Rails.application.config.action_dispatch.cookies_serializer = :json
我把它改成了

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

这就成功了

我也遇到了同样的问题,在这里使用了答案,所有问题都解决了。 在阅读了评论之后,我发现仅仅改变秘密也解决了问题,我想这应该是解决问题的办法


我认为更改密钥是解决问题的一个更好的方法,而不是切换到:如@Thibaut Barrère在评论中所述的混合模式

如果您对更改密钥感到满意,那么它将解决问题,我可以确认,使用旧cookie的人不会遇到500错误

运行
rake secret
生成新的秘密

如果您已经实现了
config/secrets.yml
,请将新密码放在那里。否则,如果您仍然在
config/initializers/secret_token.rb
中保存您的密码,请将其放入其中

不要管你的
config/initializers/session\u store.rb文件——你不需要更改它

config/initializers/cookie\u store.rb中,将其更改为
:json

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

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

我可以确认,即使您的浏览器正在存储旧的会话cookie,该功能也能正常工作。通过更改秘密,当有人使用旧会话cookie访问您的站点时,服务器将忽略旧会话状态并创建新会话。没有500个错误。

我怀疑如果以后您切换到:json,而很久以前就没有访问过您的应用程序的人回来了,同样的错误也会发生。想知道如何处理这种情况!也许改变秘密就足够了,还不确定。我认为混合
序列化程序的重点是解决您描述的场景。澄清一下:我担心(但会验证)长期保持混合激活会留下安全问题,因为yaml可以通过等。如果这是真的,在某一点上,切换到:json而不是:hybrid将是一个好主意,否则它将完全违背目的。我关心的是如何避免在切换到:json时出现错误,如果有人使用了旧cookie,就会出现错误。我将仔细研究,以了解这一部分。@ThibautBarrère我刚在将cookies_序列化程序设置为:json时遇到了这个问题。我更改了我的秘密,它工作正常,没有500个错误,尽管我的浏览器有一个旧的会话cookie。如果你同意更改你的秘密,就没有必要使用hybrid。