2012-05-02 4 views
8

bekommen Ich habe herumspielen mit Rest-Client zu einer Schiene App, die ich geschrieben habe. Ich habe ein schnelles Skript geschrieben, um mich einzuloggen und eine Postanfrage zu stellen. Alles funktioniert, aber ich musste um die Tatsache arbeiten, dass kein authenticity_token serviert wird, wenn Sie ein Formular in json anfordern. Ich musste eine normale HTML-Anfrage in anderen machen, um das authenticity_token zu bekommen, und dann dieses in den JSON einbinden, den ich als Teil meiner Postanfrage eingereicht habe. Im Prinzip habe ich ein schnelles ein schmutziges Skript wie die untencsrf Tokens für JSON Post Anfragen an eine Schiene app

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}) 

Es gibt die Option deaktivieren CSRF-Schutz für json Anfragen aber ich würde lieber nicht tun. Ich könnte die Mechanise Route oder etwas ähnliches gehen und dann würde ich mich nicht um JSON Anfragen mit CSRF kümmern, aber ich wollte nur mit diesem Zeug mit Rest-Client zu tun

Ich denke, ich bin nur neugierig zu wissen, ob es gibt einen grund, warum kein authenticity_token für json-anfragen serviert wird und ich frage mich auch, ob es eine bessere lösung für das tokenproblem gibt als den hübschen hacky-ansatz, den ich hier genommen habe

Antwort

8

Setzen sie den untenstehenden code in ihre anwendung Controller:

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

Und rufen Sie diese Methode mit before_filter.

Für weitere Informationen überprüfen: http://blog.technopathllc.com/2011/09/rails-31-csrf-token-authenticity-for.html

Und überprüfen Sie dieses Problem in Schienen: https://github.com/rails/rails/issues/3041

+1

Danke für Ihre Antwort swati, es sieht nützlich aus. Ich denke, obwohl ich versucht habe, die CSRF-Checks einfach zu deaktivieren. Es erscheint mir nur ein bisschen komisch, dass rails JSON-Formularen dienen, die kein Token enthalten, aber dann nach einem Token sucht. Wäre es sinnvoll, nur die json-Formulare mit einem Token zu versehen, anstatt die checks für json-Inhalte abzuschalten? – Conor

+0

willkommen ... ja, das ist nur eine Möglichkeit, das CSRF-Token-Problem zu umgehen. Wenn Sie Token mit Ihrer JSON-Anfrage übergeben möchten, können Sie Header wie: headers verwenden: { 'X-CSRF-Token': '<% = form_authenticity_token.to_s%>' } – swati

+0

Überprüfen Sie: http: // stackoverflow. com/questions/7203304/cant-verify-csrf-token-authenticity-rails http://stackoverflow.com/questions/8503447/rails-how-to-add-csrf-protection-to-forms-created-in -javascript – swati

0

In Ihrem app/views/products/new.json.jbuilder, fügen Sie diese:

json.authenticity_token form_authenticity_token 

Dies wird ein Schlüssel "authenticity_token" mit Wert Sein einfügen das Token, so in Ihrem json_response erhalten Sie auch das Token. Idee von this answer.

Verwandte Themen