Как я могу получить токен CSRF для передачи с запросом JSON?
Я знаю, что по соображениям безопасности Rails проверяет токен CSRF для всех типов запросов (включая JSON / XML).
Я мог бы вставить свой контроллер skip_before_filter :verify_authenticity_token
, но я потеряю защиту CRSF (не рекомендуется :-)).
Этот аналогичный (до сих пор не принятый) ответ предлагает
Получите токен с помощью
<%= form_authenticity_token %>
Вопрос как? Нужно ли мне сначала вызвать любую из моих страниц, чтобы получить токен, а затем выполнить настоящую аутентификацию с помощью Devise? Или это разовая информация, которую я могу получить со своего сервера и затем использовать постоянно (пока я не изменю ее вручную на самом сервере)?
источник
protect_from_forgery with: :null_session, :if => Proc.new { |c| c.request.format == 'application/json' }
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
2) Не имеет отношения к этому вопросу, но относится к теме POSTing JSON из iOS, поскольку я использую,AFNetworking
а Rails не обертывает параметры автоматически, я сделал следующее:manager.requestSerializer = [AFJSONRequestSerializer serializer];
Вы можете отправить токен CSRF после успешного входа в систему, используя настраиваемый заголовок.
Например, поместите это в свои сеансы # create:
response.headers['X-CSRF-Token'] = form_authenticity_token
Пример заголовка ответа для входа в систему с токеном CSRF:
HTTP/1.1 200 OK Cache-Control: max-age=0, private, must-revalidate Connection: Keep-Alive Content-Length: 35 Content-Type: application/json; charset=utf-8 Date: Mon, 22 Oct 2012 11:39:04 GMT Etag: "9d719d3b9aabd413c3603e04e8a3933d" Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-10-12) Set-Cookie: [cut for readability] X-Csrf-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw= X-Request-Id: 178746992d7aca928c876818fcdd4c96 X-Runtime: 0.169792 X-Ua-Compatible: IE=Edge
Этот токен действителен до тех пор, пока вы снова не войдете в систему или (выйдите из системы, если вы поддерживаете это через свой API). Ваш клиент может извлечь и сохранить токен из заголовков ответа на вход. Затем каждый запрос POST / PUT / DELETE должен устанавливать заголовок X-CSRF-Token со значением, полученным во время входа в систему.
Примеры заголовков POST с токеном CSRF:
POST /api/report HTTP/1.1 Accept: application/json Accept-Encoding: gzip, deflate, compress Content-Type: application/json; charset=utf-8 Cookie: [cut for readability] Host: localhost:3000 User-Agent: HTTPie/0.3.0 X-CSRF-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw=
Документация: form_authenticity_token
источник
Действительно самый простой способ. Не беспокойтесь об изменении заголовков.
Убедитесь, что у вас есть:
в вашем
layouts/application.html.erb
Просто сделайте скрытое поле ввода вот так:
<input name="authenticity_token" type="hidden" value="<%= form_authenticity_token %>"/>
Или, если вам нужен пост jquery ajax:
$.ajax({ type: 'POST', url: "<%= someregistration_path %>", data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" }, error: function( xhr ){ alert("ERROR ON SUBMIT"); }, success: function( data ){ //data response can contain what we want here... console.log("SUCCESS, data="+data); } });
В основном, когда вы публикуете свои данные json, просто добавьте к
post
данным действительное поле authentication_token, и предупреждение должно исчезнуть ...источник
= token_tag(nil)
(ноль важен)Я решил эту ошибку следующим образом:
class ApplicationController < ActionController::Base protect_from_forgery skip_before_action :verify_authenticity_token, if: :json_request? protected def json_request? request.format.json? end end
Источник: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
источник
protect_from_forgery with: :exception, unless: -> { request.format.json? }
и у меня это сработало. Благодарю.Что беспокоит, так это то, что в Rails 3.2.3 мы теперь получаем предупреждение CSRF в production.log, но сообщение не терпит неудачу! Я хочу, чтобы он провалился, потому что он защищает меня от нападок. И вы можете добавить токен csrf с помощью jquery перед фильтром btw:
http://jasoncodes.com/posts/rails-csrf-vulnerability
источник
Я использовал нижеприведенное. Используете include? поэтому, если тип содержимого - application / json; charset = utf-8, он все еще работает.
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format.include? 'application/json' }
источник
Этот ответ лучше.
Вы можете провести проверку CSRF-TOKEN без дополнительных усилий (токен добавляется) перед любой отправкой XMLHttpRequest. Нет JQuery, нет ничего, просто скопируйте / вставьте и обновите.
Просто добавьте этот код.
(function() { var send = XMLHttpRequest.prototype.send, token = $('meta[name=csrf-token]').attr('content'); XMLHttpRequest.prototype.send = function(data) { this.setRequestHeader('X-CSRF-Token', token); return send.apply(this, arguments); }; }());
источник
У меня была такая же проблема со следующей версией Rails:
gem 'rails',: git => 'git: //github.com/rails/rails.git',: branch => '3-2-stable'
Я обновился до 3.2.2, и теперь у меня все работает нормально. :)
жемчужина 'рельсы', '3.2.2'
источник
WARNING: Can't verify CSRF token authenticity
Сегодня я столкнулся с той же проблемой. Причина этого в том, что при входе в систему последний токен csrf больше не действителен. Что я сделал:
$("meta[name=csrf-token]").attr('content', '<%= form_authenticity_token %>');
в вашем приложении / views / devise / sessions / create.js.rb.Теперь у него есть действующий csrf-токен :) Надеюсь, это поможет
источник
Также для режима разработки / тестирования.
protect_from_forgery with: :exception unless %w(development test).include? Rails.env
Это предупреждение отображается, потому что вы используете
:null_session
, в Rails 4.1 оно работает по умолчанию, если неwith:
указаны параметры.источник