Posting JSON from iOS to Rails 3.1 (Stringify_keys

2019-06-03 14:53发布

问题:

I'm trying to create a user acount on my rails backend via json from an iPhone app. Here is what is currently being posted to the server:

Started POST "/patients" for 127.0.0.1 at 2011-11-27 20:52:29 -0800
  Processing by PatientsController#create as HTML
  Parameters: {"patient"=>"{\"password\":\"password\",\"password_confirmation\":\"password\",\"email\":\"testagain\"}"}
WARNING: Can't verify CSRF token authenticity
Completed 500 Internal Server Error in 1ms

NoMethodError (undefined method `stringify_keys' for #<String:0x00000104a354f8>):
  app/controllers/patients_controller.rb:43:in `new'
  app/controllers/patients_controller.rb:43:in `create'

By posting straight from the browser these are the paramaters that are submitted:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"H2iYdzdfokQs91AAozb+taMTdV2y5xLRaCni5XKQN4w=", "patient"=>{"email"=>"test", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create Patient"}

From what I have read elsewhere the stringify_keys means that the actions expects a hash (which I thought I almost reconstructed) since I am using this code to create a new user:

@patient = Patient.new(params[:patient])

I also believe that the authenticity token doesn't matter if I'm posting using JSON format... does it matter?

Over all question: Is this the right approach to be posting to a rails backend from an iphone app? Recreating the parameters hash? Would appreciate any nudges in the right direction.

For completeness sake here is the code snippet I'm using to post from my iOS app:

 NSDictionary *json = [self createSignUpDictionary];
 NSURL *url = [NSURL URLWithString:@"http://localhost:3000/patients"];
 ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
 [request addRequestHeader:@"Content-Type" value:@"application/json"];
 [request addRequestHeader:@"Accepts" value:@"application/json"];
 [request setPostValue:[json JSONString] forKey:@"patient"];
 [request startAsynchronous];

回答1:

You will most likely have to disable the authentication token verification for your action.

Just put the following line in your controller and everything should work.

protect_from_forgery :except => :index

However if you do that make sure that you have some form of custom protection on your #create function. You can read this for more info: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html