Ответ 1
Проблема решена путем понижения до 2.3.5 из 2.3.8. (а также печально известный "Вы перенаправлены".)
Ниже приведена ошибка, вызванная формой в приложении Rails:
Processing UsersController#update (for **ip** at 2010-07-29 10:52:27) [PUT]
Parameters: {"commit"=>"Update", "action"=>"update", "_method"=>"put", "authenticity_token"=>"ysiDvO5s7qhJQrnlSR2+f8jF1gxdB7T9I2ydxpRlSSk=", **more parameters**}
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
Это происходит для каждого запроса не get
, и, как видите, authenticity_token
есть.
Проблема решена путем понижения до 2.3.5 из 2.3.8. (а также печально известный "Вы перенаправлены".)
У меня была такая же проблема, но со страницами, которые были кешированы. Страницы буферизировались с использованием устаревшего токена подлинности и всех действий с использованием методов post/put/delete, которые распознавались как попытки подделки. Ошибка (422 Unprocessable Entity) была возвращена пользователю.
Решение для Rails 3:
Добавить:
skip_before_filter :verify_authenticity_token
или, как указано в "Сагиво" в Rails 4, добавить:
skip_before_action :verify_authenticity_token
На страницах, которые делают кеширование.
Как заметил @toobulkeh, это не является уязвимостью для действий :index
, :show
, но будьте осторожны, используя это для действий :put
, :post
.
Например:
caches_page :index, :show
skip_before_filter :verify_authenticity_token, :only => [:index, :show]
Ссылка: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html
Примечание, добавленное barlop- Rails 4.2, устарело skip_before_filter в пользу skip_before_action https://guides.rubyonrails.org/4_2_release_notes.html "Семейство методов * _filter было удалено из документации. Их использование не рекомендуется в пользу семейства методов * _action"
Для меня причина этой проблемы под Rails 4 отсутствовала,
<%= csrf_meta_tags %>
Линия в моем основном макете приложения. Я случайно удалил его, когда переписал свой макет.
Если это не в главном макете, вам понадобится его на любой странице, на которой вы хотите использовать токен CSRF.
Существует несколько причин этой ошибки (относящихся к Rails 4).
1. Проверьте <%= csrf_meta_tags %>
на странице макета страницы
2. токен аутентификации отправляется с помощью вызовов AJAX при использовании помощника form_for
с опцией remote: true
. Если вы не можете включить строку <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
с блоком формы.
3. Если запрос отправляется с кешированной страницы, используйте кэширование фрагментов, чтобы исключить часть страницы, которая отправляет запрос, например. button_to
и т.д. иначе токен будет устаревшим/недействительным.
Я бы не хотел сбрасывать защиту csrf...
Маркер подлинности - это случайное значение, сгенерированное, по вашему мнению, для подтверждения того, что запрос отправлен из формы на вашем сайте, а не где-то еще. Это защищает от CSRF-атак:
http://en.wikipedia.org/wiki/Cross-site_request_forgery
Проверьте, кто этот клиент /IP, похоже, они используют ваш сайт без загрузки ваших просмотров.
Если вам нужно продолжить отладку, этот вопрос - хорошее начало: Понимание токена подлинности Rails
Отредактировано для объяснения: это означает, что они вызывают действие для обработки отправки вашей формы, даже не отображая вашу форму на вашем веб-сайте. Это может быть вредоносным (например, публикация спам-комментариев) или указание на то, что клиент пытается напрямую использовать API вашего веб-сервиса. Вы единственный, кто может ответить на этот вопрос в зависимости от характера вашего продукта и анализа ваших запросов.
Просто добавив authenticity_token
в форму, исправил его для меня.
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
слишком поздно, чтобы ответить, но я нашел решение.
Когда вы определяете собственную форму html, вы пропускаете строку токена аутентификации, которая должна быть отправлена контроллеру по соображениям безопасности. Но когда вы используете рельсы для создания формы, вы получаете что-то вроде следующего
<form accept-charset="UTF-8" action="/login/signin" method="post">
<div style="display:none">
<input name="utf8" type="hidden" value="✓">
<input name="authenticity_token" type="hidden"
value="x37DrAAwyIIb7s+w2+AdoCR8cAJIpQhIetKRrPgG5VA=">
.
.
.
</div>
</form>
Таким образом, решение проблемы заключается в том, чтобы добавить поле authenticity_token или использовать рельсы из помощников, а не удалять, понижать или обновлять рельсы.
ActionController::InvalidAuthenticityToken
также может быть вызван неверно настроенным обратным прокси-сервером. Это тот случай, если в трассировке стека вы получите строку, похожую Request origin does not match request base_url
.
При использовании обратного прокси-сервера (такого как nginx) в качестве приемника для запроса HTTPS и передачи запроса в незашифрованном виде на бэкэнд (например, приложение Rails), бэкэнд (более конкретно: Rack) ожидает некоторые заголовки с дополнительной информацией об исходном клиентском запросе для того, чтобы иметь возможность применять различные задачи обработки и меры безопасности.
Более подробная информация доступна здесь: https://github.com/rails/rails/issues/22965.
TL; DR: решение состоит в том, чтобы добавить несколько заголовков:
upstream myapp {
server unix:///path/to/puma.sock;
}
...
location / {
proxy_pass http://myapp;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on; # Optional
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $host;
}
Если вы сделали rake rails:update
или иначе недавно изменили свой config/initializers/session_store.rb
, это может быть признаком старых файлов cookie в браузере. Надеюсь, это сделано в dev/test (это было для меня), и вы можете просто удалить все куки файлы браузера, связанные с данным доменом.
Если это находится в процессе производства, и вы изменили key
, подумайте об изменении его, чтобы использовать старые куки файлы (< - только спекуляция).
У меня была эта проблема с javascript-звонками. Я исправил это, просто потребовав jquery_ujs в файл application.js.
У нас была та же проблема, но заметил, что это было только для запросов с использованием http://, а не с https://. Причиной было secure: true
для session_store:
Rails.application.config.session_store(
:cookie_store,
key: '_foo_session',
domain: '.example.com',
secure: true
)
Исправлено использованием HTTPS ~ везде:)
Для рельсов 5 лучше добавить protect_from_forgery prepend: true
чем пропустить verify_authentication_token
У меня была эта проблема, и причина в том, что я скопировал и ввел контроллер в свое приложение. Мне нужно было изменить ApplicationController
на ApplicationController::Base
У меня была такая же проблема на localhost. Я изменил домен для приложения, но в URL-адресах и файле hosts все еще был старый домен. Обновил мои закладки и хосты браузера, чтобы использовать новый домен, и теперь все работает нормально.
Возможно, у вас есть настройка NGINX для HTTPS, но ваши сертификаты недействительны? У меня была аналогичная проблема в прошлом, и перенаправление с http на https решило проблему.
Я использовал что-то вроде этого, и это работает для меня.
class WelcomeController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_model!
end
Я проверил наличие <% = csrf_meta_tags%> и очистка куки в браузере сработала для меня.
Следуя рекомендациям Chrome Lighthouse для ускорения загрузки приложений, я установил асинхронный Javascript:
views/layout/application.html.erb
<%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload', async: true %>
Это сломало все и получило ошибку токена для моих удаленных форм. Удаление async: true
решило проблему.
добавлять
//= require rails-ujs
в
\app\assets\javascripts\application.js
Этот ответ гораздо более конкретен для Ruby on Rails, но, надеюсь, он кому-нибудь поможет.
Вам необходимо включать токен CSRF в каждый не GET-запрос. Если вы привыкли использовать JQuery, Rails имеет вспомогательную библиотеку под названием jquery-ujs
, которая основывается на ней и добавляет некоторые скрытые функции. Одна из вещей, которую он делает, автоматически включает токен CSRF в каждый запрос ajax
. Смотрите здесь.
Если вы откажетесь от этого, как я, вы можете оказаться с ошибкой. Вы можете просто отправить токен вручную или использовать другую библиотеку, чтобы помочь очистить токен от DOM. Смотрите этот пост для более подробной информации.
В рельсах 5 нам нужно добавить 2 строки кода
skip_before_action :verify_authenticity_token
protect_from_forgery prepend: true, with: :exception
Установка
gem 'remotipart'
может помочь