×

IDMWORKS Blog

Getting Started with OAuth2Client on iOS


OAuth2-small.png

In creating a proof-of-concept iOS app that uses OAuth2 to consume the Google APIs, I began with the OAuth2Client project by the folks at nxtbgthng GmbH. This project is one of oldest and most active OAuth2 client implementations for iOS and OS X.

However, while the project is a success, the documentation for getting started can be lacking (as other developers have noted). The documentation on their Github page covers installing the framework and some of the basic functions, but there is no documentation for using OAuth2Client from start-to-finish to accomplish a standard OAuth2 authorization flow.

This post aims to fill that gap.

Registering with the Service Provider

As stated above, this example will be using OAuth2 to connect to the Google APIs and then retrieve protected user information. In order to follow along, the first thing you’ll need to do is register the iOS application with the Google APIs Console. After creating a new project in the Google APIs Console, click the API Access item in the navigation bar and create a new client ID.

Select Installed application under Application type and iOS for the Installed application type. Then, enter your application’s Bundle ID and click Create client ID.

Once you have created your project and client ID in the Google APIs Console, you will be presented with several key identifying pieces of information that are unique to your project:

  • A client ID
  • A client secret
  • A pair of redirect URLs/URIs

Starting the Xcode Project

Once you have the above details for your project, create a new iOS project in Xcode using the Single View Application template, specifying the same Bundle ID used when registering your project with Google.

Then, follow the instructions found in the project readme on Github to add the OAuth2Client framework to your project. The easiest way to do this is using CocoaPods. If you are familiar with Maven for Java development, RubyGems for Ruby, or Nuget for .NET, CocoaPods is similar. With CocoaPods you can define your project’s dependencies in a simple text file, called a Podfile, and the pod command will take care of the rest. If you decide to use CocoaPods, your Podfile should look like the following:

 

Creating the User Interface

For this simple example, the only user interface element will be a UIWebView. Open up the iPhone.storyboard file and drag a Web View from the object library and parent it on the main view. Then, use the Assistant Editor in Xcode to create an IBOutlet for the UIWebView named loginWebView.

 

The rest of our work will all be in code.

Defining Key OAuth2 Values 

Switch to your main view controller’s .m file and add the following constants:

 

Refer to the comments above each block of constants for details on where the values were obtained. Also make sure you replace the values in the first block of constants with your own project’s values from the Google APIs Console.

Setting Up the Account Store

With these key values defined, we can now get started using OAuth2Client to establish an OAuth2 authentication flow. The first step here is to setup the NXOAuth2AccountStore. This part is documented well in the Github readme.

 

The above code will setup the OAuth2 account store with the key values obtained from the Google APIs Console.

Requesting Access

Once the account store is configured we can request access from the OAuth2 service provider. Unfortunately, this is where the documentation found on the project’s Github page starts to get a little thin. In the case of accessing Google’s APIs, we need to use the requestAccessToAccountWithType:withPreparedAuthorizationURLHandler method, using the block provided to show the login page in the UIWebView we created above.

 

With these two methods defined, we can call them from the viewDidLoad method to kick off the OAuth2 authentication flow.

 

At this point you can run the app in in the simulator or on a device. You should be presented with a Google login page, followed by a prompt to allow your app access to your user information.

Clicking the Accept button will lead you to a page that displays your authorization code in a text field. It is this authentication code that we can now use to retrieve an access token and refresh token from the OAuth2 service provider.

While not immediately obvious (but documented by Google), by using the redirect URL indicated above (not the http://localhost redirect URL but rather the one with the urn: prefix) the page not only shows the authorization code in plain text, but the title of the webpage itself contains all of the information needed to complete the access flow.

Handling the Authorization Code

To handle things automatically we need to assign our view controller as the delegate of the login UIWebView controller so we are notified when pages change.

 

The snippet of code found in webViewDidFinishLoad: checks to see if the UIWebView is on the OAuth2 authorization URL. If so the UIWebView is made visible. If the authorization page has been left, the UIWebView is hidden and the page title (containing the authentication code) is extracted.

Obtaining an Access Token

Now that we have our authentication code, how do we complete the access flow in order to obtain an access token and refresh token? This is where the project documentation goes completely silent. The answer is to take the page title contents obtained from Google – which are formatted as query string arguments – and append them to the redirect URL used to setup the OAuth2 client initially. Then, that URL must be passed to the handleRedirectURL: method of NXOAuth2AccountStore.

 

With this method defined, update the existing webViewDidFinishLoad: method to call handleOAuth2AccessResult: after obtaining a value for pageTitle. Running the application and clicking Accept should now hide the UIWebView rather than displaying the authentication code. In addition, if you check the console output for the application you should see the following:

 

NOTE that, in order for this to work with Google APIs, you may need a fix to the OAuth2Client library available here so that it can handle redirect URLs without schemes (without http:// prefix). A pull request has been submitted but, if the code doesn’t log a “Success!!” at this point, you may need to check NSURL+NXPAuth2.m and apply the fix manually:

 

Accessing Protected Content

It’s been a long trip but the hard parts are done! We can now access protected data from Google using the account information now found within the NXOAuth2AccountStore.

 

Here, the protected information we are requesting is found at https://www.googleapis.com/oauth2/v1/userinfo as documented by Google here. The account specified is the account returned by our OAuth2 authentication flow, which contains the access token and refresh token. The only thing left is to update the setupOAuth2AccountStore method to call requestOAuth2ProtectedDetails in response to the NXOAuth2AccountStoreAccountsDidChangeNotification notification:

 

Run the app one last time and click Accept. If you check the console output, you should now see the protected account details:

 

You can view a video of an iOS sample based on this code (with a bit more UI work) here

 

Questions, comments or concerns? Feel free to reach out to us below, or email us at IDMWORKS to learn more about how you can protect your organization and customers.

Comments on: “Getting Started with OAuth2Client on iOS”

  1. Thank you for providing a really wonderful tutorial.
    After following your steps, I am able to see the google login screen.
    But when trying to login using my google account, I am continuoulsy getting an error in my UIWebView controller.
    Error:invalid_client
    The OAuth client was not found.
    Request details
    cookie_policy_enforce=false
    ………….
    ………….
    ………….

    Please suggest me a solution for this issue.

    Regards,
    Alvin

  2. Nathanial – thank you for this excellent tutorial. Following it, I was able to get OAuth2Client working for an integration I am doing for my company. Your code was a tremendous help, can’t thank you enough!
    Mike

Leave a Reply

Your email address will not be published. Required fields are marked *