views:

1836

answers:

4

I'm working on an iPhone app that ideally uses OAuth to communicate with Twitter. I know a lot of people are doing the OAuth workflow inside of their apps using a UIWebView, but I don't agree with that and am going with the Pownce approach.

The problem is, Twitter has this whole scheme for working with desktop apps, using a pin number. When I register my app with Twitter, they have a web form asking me if I'm a desktop or web client. If I choose desktop client, when I try to have the user authorize, I can set the oauth_callback parameter but Twitter will ignore it after authorization and show a pin number. If, on twitter's form, I specify that I'm a web client, it requires me to enter a URL to redirect to after authorization. And, since I'm using an iPhone app-specific url scheme, their web form fails on validation as it only seems to accepts URLs conforming to the HTTP protocol.

So, it seems like I'm stuck - I can't say "desktop" because I don't want to bother with a pin, and I can't say "web" or I can't use an iPhone app URL. Any solution to this?

+6  A: 

From your question:

I know a lot of people are doing the OAuth workflow inside of their apps using a UIWebView, but I don't agree with that and am going with the Pownce approach.

The Pownce article suggests that quitting your application and opening Mobile Safari to perform the authentication step is problematic, and that they started receiving bad reviews from users for doing it that way. They also experienced a failure rate of around 40%.

Pownce's solution is to use a UIWebView within your application instead, so I have a feeling you may have misinterpreted their recommendations. That being said, they do label this as a "naive" solution and go on to suggest a bunch of theoretical "ideal" solutions.

Another point you might not realise is that desktop applications (using the "out of band" / pin number method) and web applications need to open the Twitter site in either an embedded or external browser.

So you've got two choices on the iPhone:

  1. Open up twitter.com in a UIWebView, specifying no oauth_callback parameter or oauth_callback=oob to start the pin-based out-of-band flow. The user then needs to copy the pin using the iPhone's copy-paste functionality, manually close the UIWebView, and paste the pin into your application. The pin can then be used converted to an access token.
  2. Do it how everyone else is doing it (UIWebView + custom-uri://foo.bar in the callback parameter).

For obvious reasons, the first option is pretty crap and really only useful on platforms where Twitter is unable to redirect to a custom URI.

Nathan de Vries
I did see the 40% number but wasn't sure how much I agreed with Mike's conclusion. I was actually one of the folks that fit into the 40%, as I downloaded the Pownce iPhone app then remembered that I didn't really use Pownce anyway.Looks like I'll have to go with your approach #2 though, which seems unfortunate.
bpapa
I'm interested in your opinion on why approach #2 is less than ideal. It's more work than simply entering your username/password, but what are some of the other problems?
Nathan de Vries
It's not that it's more work, but it goes against the spirit of OAuth. Instead of letting the user enter credentials into a place they trust (a page clearly owned by twitter, in mobile Safari) they are putting their information directly into my application, and who knows what I'm doing with it there.
bpapa
A: 

A simple solution may be to create an HTTP page that always sends a 301 redirect to your custom URL scheme and then provide that HTTP URL to the twitter web API.

Aside from that, Nathan's answer is very complete.

rpetrich
A: 

Here's how I do it: tell Twitter you're a web app, and make up any old HTTP:// URL to satisfy Twitter during registration of your oauth client.

Then in your app, pass the URL you want to in the callback parameter. Twitter (in my experience) uses the one you give it.

Andrew Arnott
A: 

You could use an intermediate website for the authentication. Your app creates a unique id (hardware based?) and stores it. It then records it has sent the user for authentication and sends the unique id to your website. It then redirects the user to your website. Your website then sends the user to Twitter using oAuth. The user returns to your website and you mark the unique id as authenticated and store the authentication information. The user restarts the app on the iPhone, it reads it has sent the user for authentication and contacts your website with the unique id - and reads in the authentication information.

Long winded and needs another website, but it should work.

Richy C.