2012-05-02 2 views
8

Я играл с помощью клиента rest для доступа к приложению rails, которое я написал. Я написал быстрый скрипт для входа в систему и отправки почтового запроса. Все работает, но мне приходилось работать над тем фактом, что аутентификация_token не выполняется, если вы делаете запрос для формы в json. Я должен был сделать регулярный html-запрос в другом, получить authenticity_token, а затем включить это в json, который я представил как часть моего запроса на отправку. В принципе у меня есть быстрый в грязный сценарий как один нижеПолучение токенов csrf для почтовых запросов json для приложения rails

private_resource = RestClient::Resource.new('https://mysite.com') 

params = {:user => {:email => '[email protected]', :password => 'please'}} 
#log in 
login_response = private_resource['users/sign_in'].post(params, :content_type => :json, :accept => :json) 
#get cookie 
cookie = login_response.cookies 
#get json 
json_response = private_resource['products/new'].get(:content_type => :json, :accept => :json, :cookies => cookie) 
#another request that returns html form with authenticity token 
response_with_token = private_resource['products/new'].get(:cookies => cookie) 
#extract token 
token = Nokogiri::XML(response_with_token).css('input[name=authenticity_token]').first.attr('value') 
#update cookie 
cookie = response_with_token.cookies 
#populate form and insert token 
form = JSON.parse(json_response) 
form['name'] = "my product" 
form['authenticity_token'] = token 
#submit the request 
private_resource['products'].post(form.to_json, {:cookies => cookie, :content_type => :json, :accept => :json}) 

Существует возможность отключить защиту CSRF запросов JSon, но я предпочел бы не делать этого. Я мог бы пойти на маршрут механизации или что-то подобное, и тогда я не стал бы беспокоиться о запросах json с CSRF, но я просто хотел поиграть с этим занятием с rest-client

Я думаю, мне просто интересно узнать, если есть причина, по которой для запросов json не подано никакой аутентичности_token, и мне также интересно, есть ли лучший способ решения проблемы с токеном, чем довольно хакерский подход, который я здесь сделал

ответ

8

Вставьте приведенный ниже код в ваше приложение контроллер:

def verified_request? 
    if request.content_type == "application/json" 
     true 
    else 
     super() 
    end 
end 

И вызовите этот метод, используя before_filter.

Для получения более подробной информации проверьте: http://blog.technopathllc.com/2011/09/rails-31-csrf-token-authenticity-for.html

И проверить этот вопрос в рельсах: https://github.com/rails/rails/issues/3041

+1

Спасибо за ваш ответ swati, это выглядит полезно. Наверное, хотя я пытался избежать просто отключения проверки CSRF. Мне просто кажется немного странным, что рельсы служат json-формам, которые не содержат никаких токенов, но затем проверяют токен. Было бы разумно только служить json-формам с включенным токеном, а не отключать проверки на содержание json? – Conor

+0

приветствуется ... да, это единственный способ обойти проблему токена CSRF. Если вы хотите передать токен своим запросом JSON, вы можете использовать заголовок как: headers: { 'X-CSRF-Token': '<% = form_authenticity_token.to_s%>' } – swati

+0

check: http: // stackoverflow. com/questions/7203304/warning-cant-verify-csrf-токен-аутентичность-рельсы http://stackoverflow.com/questions/8503447/rails-how-to-add-csrf-protection-to-forms-created-in -javascript – swati

0

В вашем app/views/products/new.json.jbuilder, добавьте это:

json.authenticity_token form_authenticity_token 

Это будет вставить ключ "authenticity_token" со значением бытия токен, поэтому в вашем json_response вы также получите токен. Идея от this answer.

Смежные вопросы