Подтвердить что ты не робот

Rails - недопустимый токен подлинности после развертывания

Мы используем EngineYard Cloud для развертывания нашего приложения Ruby on Rails. Мы запускаем Rails v2.3.3.

EngineYard Cloud развертывается в экземплярах AWS аналогично Capistrano. После каждого развертывания мы сталкиваемся с ошибками Notual Authenticity Token. В частности, любой пользователь, который ранее посещал наше приложение, а затем посещает его после развертывания, а затем пытается отправить форму, получает недопустимую ошибку токена аутентификации. Эта ошибка сохраняется до тех пор, пока они не будут reset содержать файлы cookie для сайта. После reset их файлов cookie сайт работает как ожидалось без ошибок.

Мы используем хранилище сеансов ActiveRecord, и сеансы сохраняются в базе данных.

Это ошибка, которую мы видим:

ActionController:: InvalidAuthenticityToken   /usr/lib/ruby/gems/ 1.8/gems/actionpack-2.3.3/lib/action_controller/request_forgery_protection.rb:79:in `verify_authenticity_token '

Объект сеанса равен нулю после развертывания, однако данные сеанса все еще сохраняются в базе данных, и файл cookie идентификатора сеанса все еще существует:

Сеанс:

  • session id: nil
  • данные: nil

Мы не смогли объяснить это. Любые мысли о том, что может быть основной причиной?

Спасибо за любые предложения!


EDIT: просто для обновления на этом мы смогли выделить пример ошибки.

1) Пользователь загружает форму 2) Код обновляется на сервере 3) Пользователь отправляет форму ** Неверная ошибка маркера подлинности.

Похоже, что когда среда изменяется, Rails не может обработать это с помощью токена аутентификации.

Мы попытались выполнить несколько шагов:

  • Сброс сеанса
  • Удаление файла cookie сеанса (как в JavaScript, так и в Rails)
  • Очистка таблицы сеанса в базе данных после развертывания кода

Ничего не работает. Единственное, что работает, - это очистить пользователей cookie на стороне клиента.

(Мы использовали Googling (даже попробовали Binging!) для ответов, но не играли в кости. Это похоже на аналогичную проблему: http://railsforum.com/viewtopic.php?id=21479)

Также: изначально мы думали, что это было изолировано от нашего развертывания до EngineYard, но мы также смогли воспроизвести его на нашем сервере разработки, который мы развертываем через Capistrano.

Любые мысли были бы с благодарностью приняты.

Спасибо!

4b9b3361

Ответ 1

ОТВЕТ: После обширной работы EngineYard (они потрясающие!) они смогли диагностировать проблему. Коренной причиной этой проблемы является ошибка с кластерами монгрелла. Кажется, что Mongrel, кажется, не видит первый запрос после начала. EngineYard проделал большую работу, чтобы диагностировать это:

В вашем коде не возникает ничего, что вызывает проблему, и я нашел людей вне нашей среды, которые также столкнулись с ошибкой (http://www.thought-scope.com/2009/07/mongrelcluster-rails-23x-bad-post.html). Я предполагаю, что многие люди этого не видят, потому что первый запрос на сайт вообще не является сообщением, или они мелят его до неудобств.

[Существует потенциальное обходное решение, использующее CURL.] Работа завитка будет выполнять простой запрос GET для каждого из ваших mogrels на сервере, чтобы загладить их так, чтобы говорить. Вы можете сделать это с помощью capistrano, но это не сработает, если вы развернете его через панель управления. Вы можете найти короткий раздел о развертывании крючков, которые мы встроили в инфраструктуру здесь: https://cloud-support.engineyard.com/faqs/overview/getting-started-with-engine-yard-cloud

Добавление прогона run curl http://localhost:500x > /dev/null должно работать (где x - порт, на котором у вас есть 5000-50005 на вашем текущая настройка).

Мы рассмотрели вопрос, переключив наш стек с Mongrel на Passenger, но, видимо, исправление для Mongrel находится в работе. Надеюсь, это поможет кому-то, кто видит эту же странную проблему.

Ответ 2

Идентификатор аутентичности - это скрытое поле в форме, которую рельсы проверяют, когда форма отправлена, чтобы гарантировать, что данные отправляются из сеанса в реальном времени.

Он существует как мера безопасности, чтобы злоумышленники не могли использовать отправку формы на своем сайте, чтобы сказать действие удаления на учетной записи someones.

Вы можете отключить его в своем приложении, добавив его в config/environment.rb

config.action_controller.allow_forgery_protection = false

Вы можете отключить его с помощью одного контроллера, используя

skip_before_filter :verify_authenticity_token

или включите его

protect_from_forgery :except => :index

ознакомьтесь с документами ActionController:: RequestForgeryProtection:: ClassMethods для более подробной информации

Ответ 3

Похоже, что секретный ключ, используемый для аутентификации, изменяется при повторном развертывании и аннулировании всех существующих сеансов.

У вас есть параметр конфигурации config.action_controller.session, установленный где угодно, и если вы это сделаете, есть ли что-нибудь, что может привести к его изменению при повторном развертывании?

В одном из моих приложений он настроен на config/environment.rb, а более поздний (сгенерированный с помощью Rails 2.3) установлен в config/initializers/session_store.rb. Настройка выглядит так:

config.action_controller.session = {
    :secret      => 'long-string-of-hex-digits'
  }

Если у вас нет этой настройки по какой-либо причине, rake secret будет генерировать ключ для вас, который затем может быть вставлен в вашу конфигурацию.

(Если это & ​​mdash; и он не изменяется вашими процессами развертывания &mdash, тогда я не знаю, что происходит.)

Ответ 4

Если бы это было только для ублюдков! Я также получаю ту же ошибку на пассажире (пользователь загружает форму, разворачивает, передает → недопустимый токен аутентификации). Было бы интересно узнать, как вы решили проблему, переключившись на пассажира? Любые дальнейшие намеки приветствуются. Я также поближе посмотрю...

Ура!

Ответ 5

У вас возникла такая же проблема с Rails 2.3 и кластером Mongrel, где секрет сеанса определенно задан в инициализаторе сеанса. Проблема возникла даже после очистки клиентских файлов cookie на клиенте.

Однако предложение сделать завиток получить запрос на всех mogrels после их перезапуска, кажется, работает - слава богу, кто-то понял это, потому что он кажется довольно чертовым неясным.

Единственная добавленная информация, которую я могу предоставить, мы используем Apache mod_proxy_balancer вместе с https перед нашими Mongrels, однако эта проблема возникла до того, как мы включили SSL. Кто-нибудь видит это с помощью haproxy в качестве балансира вместо Apache?

Ответ 7

Я никогда не разбирался в деталях, но для меня это проблема с гниением данных на стороне клиента. Если я возился с тем, как я храню свои сеансы (и, следовательно, мои данные авторизации), я время от времени получаю эту ошибку. Очистка данных частного браузера; cookies, аутентифицированные сеансы, работы, всегда решали это для меня.

Надеюсь, что это поможет.