Рельсы 4 Подлинность
Я работал над новым Rails 4-приложением (на Ruby 2.0.0-p0), когда я столкнулся с некоторыми проблемами токен аутентификации.
При написании контроллера, который отвечает на json (с помощью метода класса respond_to
), я получил действие create
, которое начал получать исключения ActionController::InvalidAuthenticityToken
, когда я попытался создать запись, используя curl
.
Я убедился, что установил -H "Content-Type: application/json"
, и я установил данные с помощью -d "<my data here>"
, но все равно не повезло.
Я попытался написать тот же контроллер, используя Rails 3.2 (на Ruby 1.9.3), и у меня не было проблем с токеном аутентификации. Я обыскал вокруг, и я увидел, что были некоторые изменения с токенами аутентификации в Rails 4. Из того, что я понимаю, они больше не будут автоматически вставлены в формы больше? Я предполагаю, что это каким-то образом влияет на типы содержимого, отличного от HTML.
Есть ли способ обойти это без необходимости запрашивать HTML-форму, выхватывать токен аутентификации, а затем делать другой запрос с этим токеном? Или я полностью упускаю то, что совершенно очевидно?
Изменить: Я просто попытался создать новую запись в новом Rails 4 приложении, используя эшафот, ничего не меняя, и я столкнулся с той же проблемой, поэтому я думаю, что это не то, что я сделал.
Ответы
Ответ 1
Думаю, я просто понял это. Я изменил (новый) по умолчанию
protect_from_forgery with: :exception
к
protect_from_forgery with: :null_session
в соответствии с комментарием в ApplicationController
.
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
Вы можете увидеть разницу, посмотрев на источник request_forgery_protecton.rb
или, более конкретно, следующие строки:
В Rails 3.2:
# This is the method that defines the application behavior when a request is found to be unverified.
# By default, \Rails resets the session when it finds an unverified request.
def handle_unverified_request
reset_session
end
В Rails 4:
def handle_unverified_request
forgery_protection_strategy.new(self).handle_unverified_request
end
Что будет вызывать следующее:
def handle_unverified_request
raise ActionController::InvalidAuthenticityToken
end
Ответ 2
Вместо отключения защиты csrf лучше добавить следующую строку кода в форму
<%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %>
и если вы используете form_for или form_tag для создания формы, то она автоматически добавит указанную выше строку кода в форму
Ответ 3
Добавление следующей строки в обработанную мной форму:
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
Ответ 4
Я не думаю, что это вообще полезно отключать защиту CSRF, пока вы не реализуете API исключительно.
При просмотре документации API Rails 4 для ActionController я обнаружил, что вы можете отключить защиту подделок на каждом контроллере или на базе метода.
Например, чтобы отключить защиту CSRF для методов, которые вы можете использовать
class FooController < ApplicationController
protect_from_forgery except: :index
Ответ 5
Произошла одна и та же проблема. Исправлено, добавив к контроллеру:
skip_before_filter :verify_authenticity_token, if: :json_request?
Ответ 6
Вы пытались?
protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? }
Ответ 7
Этот официальный документ - говорит о том, как правильно отключить защиту подделок для api
http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
Ответ 8
Это функция безопасности в Rails. Добавьте эту строку кода в форму:
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
Документацию можно найти здесь:
http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
Ответ 9
Эти функции были добавлены для защиты и защиты подделок.
Однако, чтобы ответить на ваш вопрос, вот некоторые материалы.
Вы можете добавить эти строки после имени контроллера.
Таким образом,
class NameController < ApplicationController
skip_before_action :verify_authenticity_token
Вот несколько строк для разных версий рельсов.
Рельсы 3
skip_before_filter: verify_authenticity_token
Rails 4:
skip_before_action: verify_authenticity_token
Если вы намерены отключить эту функцию безопасности для всех подпрограмм контроллера, вы можете изменить значение protect_from_forgery на : null_session в файле application_controller.rb.
Таким образом,
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
end
Ответ 10
Добавить authenticity_token: true
в тег формы
Ответ 11
Когда вы определяете собственную форму 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 или использовать рельсы, формирующие помощники, а не компрометирующие безопасность и т.д.
Ответ 12
Если вы используете jQuery с рельсами, будьте осторожны с возможностью ввода методов без проверки токена аутентификации.
jquery-ujs может управлять токенами для вас
Вы должны иметь это уже как часть jquery-rails gem, но вам может потребоваться включить его в application.js с
//= require jquery_ujs
Это все, что вам нужно - ваш вызов ajax должен теперь работать
Для получения дополнительной информации см.
https://github.com/rails/jquery-ujs
Ответ 13
Все мои тесты работали нормально. Но по какой-то причине я установил переменную среды для не-теста:
export RAILS_ENV=something_non_test
Я забыл отключить эту переменную, из-за которой я начал получать исключение ActionController::InvalidAuthenticityToken
.
После отмены $RAILS_ENV
мои тесты снова начали работать.