18 July 2011 ~ 5 Comments

OAuth support in iOS

One of the hardest things to find in iOS is support for authentication methods like OAuth. While there are many solutions one of the best in my opinion is the RestKit framework. Why? For three reasons:
  1. The ability to call restful webservices using a client which parsers JSON and XML answers directly, through SSL or HTTP Auth.
  2. Core Data support, which means you can locally persist the data received.
  3. Domain Data Object support is another killer feature. In other words, you can map JSON or XML answers to domain objects.
While this sounds like the perfect solution, is more often see API using OAuth as an authentication method and this framework unfortunately did not have support.
… until now!
The solution? I’m not about to complain about the lack fo support so worked on a fix which then I was able to contribute the code back to the project. I forked their repository and added the support. While I am waiting the patch’s acceptance, you can use the code available in my personal repository.
  1. Grab the framework from my fork, and configure everything according the installation instructions.
  2. Use it in your controllers or delegates, next there is an example.
    1. OAuth 1 support:
      RKObjectManager* objectManager = [RKObjectManager sharedManager];
      objectManager.client.baseURL = @"https://api.twitter.com";
      objectManager.client.consumerKey = @"YOUR CONSUMER KEY HERE";
      objectManager.client.consumerSecret = @"YOUR CONSUMER SECRET HERE";
      objectManager.client.accessToken = @"YOUR ACCESS TOKEN HERE";
      objectManager.client.accessTokenSecret = @"YOUR ACCESS TOKEN SECRET HERE";
      objectManager.client.forceOAuthUse = YES;
      
    2. OAuth 2 support:
      RKObjectManager* objectManager = [RKObjectManager sharedManager];
      objectManager.client.baseURL = @"YOUR API URL";
      objectManager.client.oAuth2AccessToken = @"YOUR ACCESS TOKEN";
      objectManager.client.forceOAuth2Use = YES;
      

As you see, I still need to develop the code for the handshaking process, but in the meantime you can start to consume webservices and enjoy the domain data support of this framework. Comments and improvements to the code are always welcome!

5 Responses to “OAuth support in iOS”

  1. Neubinho 31 August 2011 at 1:40 pm Permalink

    Hi,

    I’m started to use your OAuth Implementation for RestKit, but ran into a Problem:

    I need to append some GET parameters to my URL, but if I append them using your solution, I get a Problem, that the oAuth signature is not matching anymore.

    For example:

    [object Manager loadObjectsAtResourcePath:@"/v1/buddies" objectMapping:userMapping delegate:self]

    is working, while:

    [object Manager loadObjectsAtResourcePath:@"/v1/buddies?full=true" objectMapping:userMapping delegate:self]

    returns that the verification of the signature string failed.

    Am I doing it the wrong way? Or is there a bug in the implementation? Any Ideas?

  2. admin 31 August 2011 at 4:10 pm Permalink

    Thanks for your comment.
    I think the best way to pass get parameters using the framework is:

    NSDictionary* queryParams = [NSDictionary dictionaryWithObjectsAndKeys:@"What is your #1 e-mail?", @"question", @"john+restkit@gmail.com", @"answer", nil];

    RKURL* URL = [RKURL URLWithBaseURLString:@"http://restkit.org" resourcePath:@"/test" queryParams:queryParams];

    If you have doubts, you can check the unit test associated with it:

    https://github.com/rodchile/RestKit/blob/master/Specs/Network/RKURLSpec.m

    Hope this helps.

  3. Neubinho 1 September 2011 at 6:49 am Permalink

    Ok, but how do I use this RKURL with the RKClient or ObjectManager? They expect NSString as the URL?

  4. Neubinho 1 September 2011 at 9:01 am Permalink

    I investigated the problem further and it seems like that if you use any parameters with the oAuth implementation, the generated oauth_signature is no longer valid. Any idea why?

    (Tested it with [[RKClient sharedClient] get:@”/v1/buddies” queryParams:params delegate:self]; and params is a NSDictionary containing only “full” as Key for “true”.)

  5. rod 1 September 2011 at 2:18 pm Permalink

    Which version of OAuth are you using?
    In OAuth2 the signature is not longer valid, since the only encryption method used is over SSL (assuming your API use https).
    In OAuth1 yes, the signature is generated based in the URL of the rest resource (as far I know), and shouldn’t be a problem of the OAuth implementation of the framework. If you need a hand, find me in IRC: irc.freenode.net in the RestKit channel (#RestKit).My nickname is rodchile.