📜 ⬆️ ⬇️

Yandex OAuth authorization in iOS

For calls to the Yandex API, the application needs a token. You can get it in two ways. The first way is the easiest - ask the user for his username and password and make a POST request to oauth.yandex.ru/token . But there are a couple of problems: the user may not want to entrust his account password to a third-party application, and Yandex itself does not recommend doing so. The second is a bit more complicated to implement and is the subject of the topic - OAuth authorization.

Application registration


The procedure is described in detail at api.yandex.ru/oauth/doc/dg/tasks/register-client.xml .

At the registration stage, we come up with a url-scheme


')
And remember the application Id



Possible implementation options


Again we read the documentation and we understand that we need to display the user a web page from which, after successful authorization, the url will be redirected to the scheme we specified during the registration stage.

There are two possible approaches.
1) Register the application by the processor of the specified URL scheme in the system. Open the Safari user with an authorization form and wait for the application to restart.
Application registration by the URL scheme handler is described in detail here.

2) We show UIWebView and in its delegate methods we catch the transition according to our scheme.

The second approach seems to me more simple, because first, the user does not leave our application, and secondly, authorization through Yandex can be the only way to enter our application.

Write the code


Create a test project in Xcode.





Add to the project YandexOauthViewController. * (Link to the source code at the end of the article).

In YandexOauthViewController.h, in the following lines, we change the values ​​to yours:

#define URL_SCHEME @"iostestapp"
#define CLIENT_ID @"6ef1c6dc6f134a2daa67cc905e5c1a3d"


In ViewController.h, we import YandexOauthViewController.h and declare ourselves the "implementer" of the YandexOauthViewControllerDelegate protocol.

#import <UIKit/UIKit.h>

#import "YandexOauthViewController.h"

@interface ViewController : UIViewController <YandexOauthViewControllerDelegate>

@end


In the test application, we will authorize the user at startup. To do this, we change the ViewDidLoad method in ViewController.m:

 - (void) viewDidLoad
 {
     [super viewDidLoad];
	 // Do any additional setup after loading the view, typically from a nib.
    
     YandexOauthViewController * cntrl = [[YandexOauthViewController alloc] init];
     cntrl.delegate = self;
     [self.navigationController presentModalViewController: cntrl animated: YES];
 }


What kind of self.navigationController you ask and you are right - there is no controller navigation yet, therefore we add it to AppDelegate.m:

 - (BOOL) application: (UIApplication *) application didFinishLaunchingWithOptions: (NSDictionary *) launchOptions
 {
     self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
     // Override point for customization after application launch.
     self.viewController = [[ViewController alloc] initWithNibName: @ "ViewController" bundle: nil];
    
     UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController: self.viewController];
    
     self.window.rootViewController = nav;
     [self.window makeKeyAndVisible];
     return YES;
 }


Run the application and see the authorization form we need.



The button on the left (with a cross) removes the authorization form from the screen, and the right button returns the user to the authorization page. The fact is that in some cases, Yandex loses the purpose of our entry into authorization and displays the user profile from which the token will not be transferred to us.

After entering the login password and, in some cases, confirming the permanent authorization on this device, Yandex redirects us to the URL scheme of the specified application registration. Consider intercepting this transition in the YandexOauthViewController.m file.

 - (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest: (NSURLRequest *) request navigationType: (UIWebViewNavigationType) navigationType
 {
     // Get the URL
     NSURL * url = [request URL];
    
     // Check for compliance with custom URL scheme
     if ([url.scheme isEqualToString: URL_SCHEME])
     {
         // remove the network activity indicator
         UIApplication * app = [UIApplication sharedApplication];
         app.networkActivityIndicatorVisible = NO;
        
         // parse the URL into separate elements
         // our token will be in the arr array at index 2
         NSArray * arr = [[url description] componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString: @ "# = &"]];
        
         // tell the delegate about successful authorization and pass the token
         if ([delegate respondsToSelector: @selector (yandexOauthViewController: succesfullLoginWithToken :)])
         {
             [delegate yandexOauthViewController: self succesfullLoginWithToken: [arr objectAtIndex: 2]];
         }
        
         // do not allow UIWebView to open URL
         return NO;
     }
    
     // allow UIWebView to navigate by URL
     return YES;
 }


It remains to implement the YandexOauthViewControllerDelegate protocol in ViewController.m.

 - (void) yandexOauthViewController: (YandexOauthViewController *) controller 
          succesfullLoginWithToken: (NSString *) token
 {
     [self.navigationController dismissModalViewControllerAnimated: YES];
    
     UIAlertView * alert = [[UIAlertView alloc] initWithTitle: @ "Authorization succeeded" 
                                                     message: [NSString stringWithFormat: @ "Token% @", token]                                                    
                                                    delegate: nil 
                                           cancelButtonTitle: @ "Ok" 
                                           otherButtonTitles: nil];
    
     [alert show];
 }




Thanks to everyone who read to this place.

Links


1) Project: github.com/eltiren/YandexOauth
2) Documentation for Yandex OAuth: api.yandex.ru/oauth/doc/dg/concepts/About.xml

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


All Articles