2012-05-02 19 views
8

He estado jugando con el uso de rest-client para acceder a una aplicación de rieles que he escrito. He escrito una secuencia de comandos rápida para iniciar sesión y hacer una solicitud posterior. Todo está funcionando, pero tuve que trabajar en torno al hecho de que no se sirve authenticity_token si solicitas un formulario en json. Tuve que hacer una solicitud html regular en otro para obtener la autenticidad_token y luego incluí esto en el json que presenté como parte de mi solicitud posterior. Básicamente tengo una rápida una escritura sucia como la de abajoobteniendo tokens csrf para las solicitudes de json post a una aplicación de rieles

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

Existe la opción de desactivar la protección CSRF para solicitudes JSON pero yo preferiría no hacerlo. Podría ir por la ruta del mecanizado o algo similar y no me preocuparía por las solicitudes json con CSRF, pero solo quería jugar con rest-client

Creo que tengo curiosidad por saber si hay una razón por la cual no se sirve authenticity_token para solicitudes json y también me pregunto si hay una forma mejor de resolver el problema del token que el enfoque bastante hacky que he tomado aquí

Respuesta

8

Ponga el siguiente código en su aplicación Controlador:

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

Y llame a este método utilizando before_filter.

Para más información Comprobar: http://blog.technopathllc.com/2011/09/rails-31-csrf-token-authenticity-for.html

y comprobar esta cuestión en rieles: https://github.com/rails/rails/issues/3041

+1

Gracias por su respuesta swati, parece útil. Creo que estaba tratando de evitar simplemente apagar las comprobaciones de CSRF. Me parece un poco extraño que los rieles sirvan formas json que no contengan ningún token, pero luego comprueba si hay un token. ¿Tendría sentido simplemente servir los formularios json con un token incluido en lugar de desactivar los controles para el contenido json? – Conor

+0

bienvenido ... sí, esa es la única forma de eludir el problema del token CSRF. Si desea pasar un token con su solicitud JSON, puede usar un encabezado como: encabezados: { 'X-CSRF-Token': '<% = form_authenticity_token.to_s%>' } – swati

+0

check: http: // stackoverflow. com/questions/7203304/warning-cant-verify-csrf-token-authenticity-rails http://stackoverflow.com/questions/8503447/rails-how-to-add-csrf-protection-to-forms-created-in -javascript – swati

0

En su app/views/products/new.json.jbuilder, añadir lo siguiente:

json.authenticity_token form_authenticity_token 

Se trata de introducir una clave "authenticity_token" con el ser de valor el token, entonces en tu json_response obtienes el token también. Idea desde this answer.

Cuestiones relacionadas