views:

655

answers:

2

I am trying to do an HTTP POST to create an instance of a model in my Ruby on Rails app from my Cocoa app. I am writing both the client (Cocoa) and server (Rails) so I can make changes in either location.

I am running into a problem with the authentication token that is required when using Protect From Forgery

All is fine when I can set the Content-Type for an HTTP POST to text/xml as Rails routes this to the appropriate xml handler which does not require an authentication token. Model objects are created, linked together and stored properly. Sweet.

I am now trying to upload a file to the server. This requires me to use a multipart/form-data Content-type. This connection fails because I the authentication token doesn't verify. Because I'm not sending an xml POST, I need to authenticate. But, I'm on a desktop client that can't make use of the nifty form helpers in rails.

What's the appropriate way around this issue?

My file upload HTTP POST works fine when I turn off Protect From Forgery but that's not an ideal solution.

Thanks, Jeff

A: 

One way around this would be to create a separate action in your controller for this particular upload. Then you can declare the following in that controller.

skip_before_filter :verify_authenticity_token, :only => :my_special_action

Of course this will expose this upload action to remote post submits. But you're trying to do just that aren't you? Remote submit something. So you can't protect from remote submits and use it at the same time. There are a couple of ways I see around that.

  • API tokens. If your upload API is only intended for use with your desktop app - you should have a token distributed with desktop app which is validated on rails side by your code.
  • If you intend to let anyone with their own app to post to your api, let them request a token so you can filter out spammers later.
  • If it's free open token-less access, then you should be ok that some junk will get through.

P.S. Another way to go could be to require basic authentication for this action if your site has accounts.

hakunin
A: 

Just a little solution, it might work on your case:

skip_before_filter :verify_authenticity_token, :only => :get_auth_token

generate the token

then send back to your app through XML call

then use that token for future references.

DucDigital
This is essentially what I did, except that I actually pull down the authentication token for each upload and still require the verify.
Jeff Hellman