📜 ⬆️ ⬇️

oAuth for iOS apps

Screen greeting club Trellj for iPhone
It was getting dark. Warm August Saturday predisposed to the implementation of oAuth authorization on Google and Facebook for iOS client of the club of intellectual games.

A superficial web search hinted to us that both companies provide tools for developers to automate this routine as quickly as possible and to return to more interesting tasks of directly programming the gameplay.

Quick links to the libraries themselves: Google - gtm-oauth2 , Facebook - facebook-ios-sdk
')
About the nuances of integration under the cat.


Google


First of all, go to the API Console and get Client ID and Client Secret there. The procedure is quick and free.

We connect to the project library gtm-oauth2. On the google authorization button we hang something like:

#import "GTMOAuth2ViewControllerTouch.h" ... - (void)onGoogleAuth:(id)sender { GTMOAuth2ViewControllerTouch *viewController; viewController = [[[GTMOAuth2ViewControllerTouch alloc] initWithScope:@"https://www.googleapis.com/auth/userinfo#email" clientID:@OAUTH_GOOGLE_CLIENT_ID clientSecret:@OAUTH_GOOGLE_CLIENT_SECRET keychainItemName:@"OAuth2 MYAPP: Google" delegate:self finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease ]; [[self navigationController] pushViewController:viewController animated:YES]; } 

This will open the ViewController with a browser and a standard web authentication request from Google. After the user passes the email and password entry procedure, the following function is called, where you can already receive a confirmed email from the logged in user and respond to the fact of a successful login:

 - (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error { if (error != nil) { // Authentication failed } else { if (auth.canAuthorize){ // auth.userEmail } } } 

In our task this was enough, but the Google API is not limited to this, and through different scope you can request rights to work with many Google services. Including youtube and buzz.

Facebook


Facebook is a bit more complicated. First, as usual, you need to register your “application” here , if, of course, you have not done this before.

Next, install the facebook-ios-sdk project, add the implementation of the FBSessionDelegate and FBRequestDelegate protocols to the delegate of your application class.

 #import "FBConnect.h" @interface AppDelegate : NSObject <UIApplicationDelegate, FBSessionDelegate, FBRequestDelegate> { UIWindow *window; .... Facebook* facebook; } .... - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url; - (void)fbDidLogin; - (void)request:(FBRequest *)request didLoad:(id)result; </pre></code>      : <code><pre> - (void)facebookLogin { if (!facebook) facebook = [[Facebook alloc] initWithAppId:@FACEBOOK_APP_ID]; [facebook authorize:nil delegate:self]; } - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { return [facebook handleOpenURL:url]; } - (void)fbDidLogin { [facebook requestWithGraphPath:@"me" andDelegate:self]; } - (void)request:(FBRequest *)request didLoad:(id)result { // result - NSDictionary }; 


Visually, it looks like a way out of the application, opening a separate Safari process, a web login and confirmation form from Facebook, closing the browser and reopening the application with an already logged in user. Indeed, the browser is executed as a separate process from the application. But how does the application intercept the return from the browser? Casket opens relatively simple. In the info.plist of your application, we register the type of URL that intercepts your application, after which Safari becomes “in the know” where to transfer control. We do this from Xcode as follows (instead of YOUAPPID, we write our application ID on Facebook):

Editing info.plist to handle external URLs


Voila, it remains in the request didLoad function to make a reaction to the user's Facebook input, and the trick is done.

Facebook request of rights, storage of session keys in KeyChains, and other goodies are described in detail in the documentation. For our purposes (simple authentication), the above described was enough, but the API capabilities are quite wide there. Up to "post a photo on the wall" and "send a message to a friend on xmpp in the end."

Friday the 13th


No, we are not a maniac in a hockey mask and with a huge cleaver. It will be a question of a small fly in the ointment, which was expressed in the fact that everyone, for some reason, consider it their duty to shove into their “library” of two classes, ELSE one JSON implementation. Citizens, when will it stop? Moreover, both Google and Facebook use the same implementation. Namely SBJSON, with different versions and incompatible interfaces. A simple file, of course, solves the problem, but, I'm afraid, because of the lack of a regular Apple implementation, iOS is time for developers to come up with a new term Json-Hell.

Keep the JSON implementation in the project (as well as zlib, and other stuff) in a single copy, and may the force be with you.

Source: https://habr.com/ru/post/126258/


All Articles