Rails 4: не могу проверить подлинность токена CSRF, но данные все еще вставляются в базу данных
Я применяю CSRF в Controller, добавив это:
class ApplicationController < ActionController::Base
protect_from_forgery
end
и я делаю почтовый запрос к моему API, используя Почтальон. Забавный результат - я не могу проверить CSRF, но данные, которые я отправляю, все равно будут вставлены в БД.
Вот журнал сервера.
Processing by Api::ListingsController
Parameters: {"listing"=>{...}}
Can't verify CSRF token authenticity
(0.2ms) BEGIN
SQL (0.6ms) INSERT INTO "listings" ...
(0.4ms) COMMIT
Completed 201 Created in 54ms (Views: 0.2ms | ActiveRecord: 6.3ms)
Кажется, все в порядке, и данные в БД сейчас! Почему CSRF не работает?
Кто-нибудь может дать какие-нибудь объяснения?
2 ответа
Существует три поведения, которые может вызвать несовпадение токена csrf:
- поднять исключение (
:exception
) - сбросить сеанс на новый, пустой сеанс (
:reset_session
) - использовать пустую сессию для запроса, но не сбрасывать ее полностью (
:null_session
)
Обоснование для последних 2 заключается в том, что целью CSRF-атаки обычно является злоупотребление тем фактом, что пользователь уже вошел в систему, и, следовательно, браузер будет отправлять сеансовые куки-файлы с запросом. Поэтому сброс или игнорирование сеанса (при условии, что именно там хранятся учетные данные) сделает запрос продолженным как неаутентифицированный запрос.
Если приложение не требует, чтобы пользователь вошел в систему, то :null_session
а также :reset_session
позволит запрос продолжить.
Поведение по умолчанию изменилось за эти годы, но по состоянию на рельсы 4.2 это :null_session
, Вы можете изменить его, указав with
возможность protect_from_forgery
В ApplicationController
можете добавить
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
# Or
# skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }
end