Rails 4 Aggiorna JSON :: Parseerror per vecchie sessioni
-
21-12-2019 - |
Domanda
Dopo l'aggiornamento a Rails 4.1.4 Dalle rotaie 3.2, l'accesso all'applicazione con una sessione esistente (dalla versione più vecchia 3,2) provoca un errore interno del server.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'
...
.
Ho provato a modificare il nome della chiave del cookie di sessione, ma sembra essere bloccato su session_id
.
# initializers/session_store.rb
MyApp::Application.config.session_store :cookie_store, key: 'myapp_session'
.
Aiuto!Una grande soluzione sarebbe anche quella di eliminare tutti i cookie di sessione prima che colpiscano il middleware dei binari, ma non ho idea di come farlo ..
Soluzione
Trovato la risposta qui: https://github.com/rails/rails/issues/15111 .
Le mie impostazioni avevano
# initializers/cookie_serializer.rb
Rails.application.config.action_dispatch.cookies_serializer = :json
.
L'ho cambiato in
Rails.application.config.action_dispatch.cookies_serializer = :hybrid
.
E questo ha fatto il trucco
Altri suggerimenti
Se sei a tuo agio con il cambiamento della tua chiave segreta, allora risolverà il problema, e posso confermare che le persone con vecchi cookie non incontreranno un errore di 500.
Esegui rake secret
per generare un nuovo segreto.
Se hai implementato config/secrets.yml
, metti il nuovo segreto lì dentro.Altrimenti, se hai ancora il tuo segreto in config/initializers/secret_token.rb
, mettilo lì dentro.
Lasciare il tuo file config/initializers/session_store.rb
da solo - non è necessario cambiarlo.
In config/initializers/cookie_store.rb
, modificalo su :json
:
# Be sure to restart your server when you modify this file.
Rails.application.config.action_dispatch.cookies_serializer = :json
.
Posso confermare che funziona, anche quando il tuo browser memorizza un antico cookie di sessione.Cambiando il segreto, quando qualcuno con un antico cookie di sessione visita il tuo sito, il server ignora semplicemente il vecchio stato di sessione e crea una nuova sessione.Nessun errore 500
Ho appena avuto lo stesso problema e ho usato la risposta qui e tutto è stato risolto. Dopo aver letto i commenti anche se ho scoperto che solo cambiare il segreto ha anche risolto il problema, come dovrei suppongo.
Penso che il cambiamento del segreto sia una soluzione migliore per il problema che passare a: ibrido come @thibaut barrère indicato nei commenti