Authenticated Google Cloud Endpoint call from an iOS client

In my last post I mentioned the Google Cloud Endpoint framework which is a great way to produce an API that can be consumed across multiple platforms. Even though it is in preview release and subject to some teething problems, I highly recommend checking it out.

In a nutshell, the framework allows you to develop a backend and then generates the necessary data and proxy classes to use in your client projects to talk to the API. This means you no longer have to be concerned with the mechanics of making an API call, parsing the response data, etc., but can interface with the entire API through objects.

I’ve been playing around with the framework in bits and pieces and recently explored making an authenticated API call from an iOS client when I discovered a rather annoying issue: after successfully authenticating a user with OAuth 2, the local dev server would reject any subsequent API calls with the following error:

Cannot authorize request with scheme http

My iOS simulator and local dev server were just not getting along….

I knew that the problem was my local dev server was plain old http and that something, somewhere required https. After several attempts and the lack of any obvious info online, I started digging around the source code of the generated client classes…and, bingo!

The problem turned out to be that the iOS OAuth2 library would not authorize non-https requests, which meant I could not test authenticated calls locally. I eventually found a flag in the GTMOAuth2Authentication class of the iOS OAuth2 library which allows the library to authorize all requests (including non-https):

// Property indicating if this object will authorize plain http request
// (as well as any non-https requests.) Default is NO, only requests with the
// scheme https are authorized, since security may be compromised if tokens
// are sent over the wire using an unencrypted protocol like http.
@property (assign) BOOL shouldAuthorizeAllRequests;

By default this flag is set to NO. To update this flag to work with my outgoing requests, I changed its value in the OAUTH callback method prior to making any API requests:

- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
      finishedWithAuth:(GTMOAuth2Authentication *)auth
                 error:(NSError *)error {
    [self dismissViewControllerAnimated:YES completion:nil];

    if (error != nil) {
        // Authentication failed
        ...
    } else {
        // Authentication succeeded
        ...

        // TODO: for development purposes only to use non-https....remove for release.
        auth.shouldAuthorizeAllRequests = YES;

        // Make some API calls
        ...
    }
}

Ta-da.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s