2

I'm trying to write a small rake task / test script for a rails RESTful API. I'm using the rest-client gem.

According to the doumentation the following should work (with app.domain obviously changed)

response =  RestClient.post "http://app.domain.com/company/v1", {'company_name' => 'Acme'}.to_json, :content_type => 'application/json', :accept => :json

However I'm getting a 422 Unprocessable Entity response.

I had gotten the same response earlier when using Net:HTTP and saw that I needed to do

request["Content-Type"] = "application/json"

to handle the CSRF issue. In worked in that case but now I'm trying to use RestClient.

The RestClient code above would seem to handle it but I'm not having any luck. I'm fine doing either a put or a post but neither is working and I've been unable to find such examples online. Has anyone been able to get this to work? I'm using the latest version RestClient 1.6.7


EDIT

Below is the production.log file for the above call

I, [2013-10-03T14:35:08.982428 #7677]  INFO -- : Started PUT "/company/v1.json" for XXX.XXX.XXX.XXX at 2013-10-03 14:35:08 +0000
I, [2013-10-03T14:35:08.992628 #7677]  INFO -- : Processing by CompaniesController#add_company as JSON
I, [2013-10-03T14:35:08.992709 #7677]  INFO -- :   Parameters: {"company_name"=>"Acme", "company"=>{"company_name"=>"Acme"}}
W, [2013-10-03T14:35:08.992974 #7677]  WARN -- : Can't verify CSRF token authenticity
I, [2013-10-03T14:35:08.993194 #7677]  INFO -- : Completed 422 Unprocessable Entity in 0ms
F, [2013-10-03T14:35:08.995424 #7677] FATAL -- :
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
  actionpack (4.0.0) lib/action_controller/metal/request_forgery_protection.rb:163:in `handle_unverified_request'
  actionpack (4.0.0) lib/action_controller/metal/request_forgery_protection.rb:170:in `handle_unverified_request'
  actionpack (4.0.0) lib/action_controller/metal/request_forgery_protection.rb:177:in `verify_authenticity_token'
  activesupport (4.0.0) lib/active_support/callbacks.rb:377:in `_run__389768266939471454__process_action__callbacks'
  activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.0) lib/abstract_controller/callbacks.rb:17:in `process_action'
  actionpack (4.0.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  activesupport (4.0.0) lib/active_support/notifications.rb:159:in `block in instrument'
  ...

It's also interesting to note that the parameters aren't correct although I though I was following the post example from the documentation. (Post and put both give me the same errors in the log.)

hershey
  • 465
  • 1
  • 8
  • 19
  • Do you have the access to API log? Is it possible to get the log from the API for this request? – usha Oct 02 '13 at 22:12
  • Good question, I just added it to the post above. – hershey Oct 03 '13 at 14:45
  • 1
    The service is expecting an auth token. `ActionController::InvalidAuthenticityToken`. But it should return 401 Unauthorized instead of unprocessable entity. – usha Oct 03 '13 at 14:51

2 Answers2

4

As a work around Alex Coco's blog post talks about using :null_session specifically

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  #protect_from_forgery with: :exception                   # default code
  protect_from_forgery with: :null_session                 # modification
end

Which if you look at the file is what they suggest doing.

Caveat: from what I understand this sets the systems strategy which means if you like putting a head on your RESTful services (in Rail's it's cheap to get a head and it's an easy way to poke around, especially if you want your non-technical staff to be able to check on something but don't want to and/or can't give them data access) I believe this turns off protection for that, too. Of course, web-access to the head for the service is likely behind a firewall in most cases so it's probably ok.

hershey
  • 465
  • 1
  • 8
  • 19
0

You can try skip_before_action :verify_authenticity_token in your controller where you are getting csrf token error

Ravindra
  • 1,039
  • 2
  • 12
  • 26