Для вызовов API Яндекса приложению нужен токен. Получить его можно двумя способами. Первый способ самый простой — спрашиваем у пользоватея его логин и пароль и делаем POST-запрос на oauth.yandex.ru/token. Но есть пара проблем: пользователь может не захотеть доверить свой пароль от учетной записи стороннему приложению, да и сам Яндекс не рекомендует так делать. Второй немного более сложный в реализации способ и является предметом топика — OAuth авторизация.
Процедура подробно описана на api.yandex.ru/oauth/doc/dg/tasks/register-client.xml.
На этапе регистрации придумываем url-схему
И запоминаем Id приложения
Снова читаем документацию и понимаем что нам надо отобразить пользователю веб-страницу, с которой после успешной авторизации произойдет редирект на url со схемой которую мы указали на этапе регистрации.
Тут возможны два подхода.
1) Регистрируем приложение обработчиком указанной URL-схемы в системе. Открываем пользователю Safari с формой авторизации и ждем перезапуска приложения.
Регистрация приложения обработчиком URL-схемы подробно описана здесь
2) Показываем UIWebView и в его делегатских методах отлавливаем переход по нашей схеме.
Второй подход мне кажется более простым, т.к. во-первых пользователь не покидает наше приложение, а во-вторых авторизация через Яндекс может быть едиственным способом входа в наше приложение.
Создаем тестовый проект в XCode.
Добавляем в проект YandexOauthViewController.* (ссылка на исходный код в конце статьи).
В YandexOauthViewController.h изменяем в следующих строках значения на ваши:
Во ViewController.h импортируем YandexOauthViewController.h и обявляем себя «реализатором» протокола YandexOauthViewControllerDelegate.
В тестовом приложении будем авторизировать пользвателя при запуске. Для этого во ViewController.m изменяем метод ViewDidLoad:
Какой еще self.navigationController, спросите вы и будете правы — навигейшен контроллера еще нет, поэтому добавляем его в AppDelegate.m:
Запускаем приложение и видим так нужную нам форму авторизации.
Кнопка слева (с крестиком) убирает форму авторизации с экрана, а правая кнопка возвращает пользователя на страницу авторизации. Дело в том, что в некоторых случаях Яндекс теряет цель нашего захода в авторизацию и и отображает профиль пользователя из которого нам токен уже не передадут.
После ввода логина пароля и, в некоторых случаях, подтверждения постоянной авторизации на данном устройстве Яндекс перенаправляет нас по URL-схеме указанной прирегистрации приложения. Рассмотрим перехват этого перехода в файле YandexOauthViewController.m.
Осталось в ViewController.m реализовать протокол YandexOauthViewControllerDelegate.
Спасибо всем кто дочитал до этого места.
1) Проект: github.com/eltiren/YandexOauth
2) Документация по Яндекс OAuth: api.yandex.ru/oauth/doc/dg/concepts/About.xml
Регистрация приложения
Процедура подробно описана на api.yandex.ru/oauth/doc/dg/tasks/register-client.xml.
На этапе регистрации придумываем url-схему
И запоминаем Id приложения
Возможные варианты реализации
Снова читаем документацию и понимаем что нам надо отобразить пользователю веб-страницу, с которой после успешной авторизации произойдет редирект на url со схемой которую мы указали на этапе регистрации.
Тут возможны два подхода.
1) Регистрируем приложение обработчиком указанной URL-схемы в системе. Открываем пользователю Safari с формой авторизации и ждем перезапуска приложения.
Регистрация приложения обработчиком URL-схемы подробно описана здесь
2) Показываем UIWebView и в его делегатских методах отлавливаем переход по нашей схеме.
Второй подход мне кажется более простым, т.к. во-первых пользователь не покидает наше приложение, а во-вторых авторизация через Яндекс может быть едиственным способом входа в наше приложение.
Пишем код
Создаем тестовый проект в XCode.
Добавляем в проект YandexOauthViewController.* (ссылка на исходный код в конце статьи).
В YandexOauthViewController.h изменяем в следующих строках значения на ваши:
#define URL_SCHEME @"iostestapp"
#define CLIENT_ID @"6ef1c6dc6f134a2daa67cc905e5c1a3d"
Во ViewController.h импортируем YandexOauthViewController.h и обявляем себя «реализатором» протокола YandexOauthViewControllerDelegate.
#import <UIKit/UIKit.h>
#import "YandexOauthViewController.h"
@interface ViewController : UIViewController <YandexOauthViewControllerDelegate>
@end
В тестовом приложении будем авторизировать пользвателя при запуске. Для этого во ViewController.m изменяем метод ViewDidLoad:
- (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]; }
Какой еще self.navigationController, спросите вы и будете правы — навигейшен контроллера еще нет, поэтому добавляем его в 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; }
Запускаем приложение и видим так нужную нам форму авторизации.
Кнопка слева (с крестиком) убирает форму авторизации с экрана, а правая кнопка возвращает пользователя на страницу авторизации. Дело в том, что в некоторых случаях Яндекс теряет цель нашего захода в авторизацию и и отображает профиль пользователя из которого нам токен уже не передадут.
После ввода логина пароля и, в некоторых случаях, подтверждения постоянной авторизации на данном устройстве Яндекс перенаправляет нас по URL-схеме указанной прирегистрации приложения. Рассмотрим перехват этого перехода в файле YandexOauthViewController.m.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { //Получаем URL NSURL *url = [request URL]; //Проверяем на соответствие пользовательской URL-схеме if ([url.scheme isEqualToString:URL_SCHEME]) { //убираем индикатор сетевой активности UIApplication* app = [UIApplication sharedApplication]; app.networkActivityIndicatorVisible = NO; //разбираем URL на отдельные элементы //наш токен будет в массиве arr под индексом 2 NSArray *arr = [[url description] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"#=&"]]; //говорим делегату об успешной авторизации и передаем токен if ([delegate respondsToSelector:@selector(yandexOauthViewController:succesfullLoginWithToken:)]) { [delegate yandexOauthViewController:self succesfullLoginWithToken:[arr objectAtIndex:2]]; } //запрещаем UIWebView открывать URL return NO; } //разрешаем UIWebView переход по URL return YES; }
Осталось в ViewController.m реализовать протокол YandexOauthViewControllerDelegate.
- (void)yandexOauthViewController:(YandexOauthViewController *)controller succesfullLoginWithToken:(NSString *)token { [self.navigationController dismissModalViewControllerAnimated:YES]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Авторизация удалась" message:[NSString stringWithFormat:@"Токен %@",token] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }
Спасибо всем кто дочитал до этого места.
Ссылки
1) Проект: github.com/eltiren/YandexOauth
2) Документация по Яндекс OAuth: api.yandex.ru/oauth/doc/dg/concepts/About.xml