Работаем с Вконтакте API. Часть 1 - Авторизация.
5 февраля 2011
Уровень сложности: для начинающих
Аннотация
ВКонтакте — ресурс не требующий представления. Это и вторая по величине соц. сеть в мире, и огромнейшее хранилище различного аудио- и видеоконтента.
Интерес разработчиков к ВКонтакте вполне объясним — миллионы активных пользователей каждый день, а также, довольно выгодная партнерская модель размещения приложений.
Немаловажную роль в этом играет и довольно удобный API. Вот о нем как раз и пойдет речь.
Первое, с чего следует начать — авторизация приложения. Сделать это можно двумя способами.
Способ рекомендуемый
Заключается вот в чем: вы встраиваете в ваше приложение компонент браузера (например, UIWebVew, если это iPhone-приложение), который направляете по адресу: http://vkontakte.ru
/login.php?app=ID_OF_
YOUR_APP&layout=popup&type=browser&settings=SETTINGS (где ID_OF_YOUR_APP — идентификационный номер вашего приложения, а SETTINGS — битовая маска прав доступа, например 16383 — полный доступ к аккаунту пользователя. Подробнее на странице права приложений ВКонтакте).
После перехода по этой ссылке, пользователь увидит окошко авторизации, где ему будет предложено ввести пароль и e-mail. Если все введенные данные верны, сервер Вконтакте перенаправит ваш браузер на адрес вида: http://vkontakte.ru/a
pi/login_success.html
#session='mid':66748,'sid':'ea56492j61334be88e2e8e1dccd21ef8d2f4606f26
add88b2e1ee313e2','
secret':'733mf8a8c5',
'expire':0,'sig':'f7afd3db2d3
a8a08c849bb038fd52173
'}. Т.е. все нужные параметры для взаимодействия с API будут «лежать» в адресной строке. Вам остается ее только обработать и получить нужные значения. (Пример того, как это можно сделать — метод dictionaryFromParsingAgruments из прилагаемого проекта).
Параметры авторизации
| mid | ID текущего пользователя | sid | Идентификатор текущей сессии | secret | Ключ-секрет сессии | expire | Время истечения сессии в формате UNIX |
Что нужно сделать, чтобы получить ID своего приложения?
- Перейдите на страницу создания нового приложения ВКонтакте и зарегистрируйте свое приложение (т.е. выберите название и установите тип на «Desktop-приложение»).
- На появившейся после успешной регистрации, перейдите на вкладку «Настройки» (в меню справа).Там вы увидите ID своего приложения.
К плюсам данного метода можно отнести относительную безопасность его для пользователя — приложение напрямую не работает с логином и паролем (т.е. и украсть их будет проблематично). Однако, мы ведь с вами не злоумышленники, верно? :) Да и к тому же далеко не каждого устроит необходимость встраивать в свое приложение еще и браузер (вдруг вы пишите консольное приложение?).
Для таких «инакомыслящих» существует еще один способ авторизовать пользователя — без использования компонента браузера. Хочется добавить, что такой способ категорически не приветствуется администрацией ВКонтакте, причина — указана выше.
Способ неявный, но действенный
В общих чертах он заключается в следующем:
- Отправляем банальный запрос с нашими данными (пароль, почта, ИН приложения) на стандартную (не для приложений) авторизацию пользователя . Нас, конечно не авторизуют, но вот нужные куки мы получим.
- В страничках логина лежит множество внутренних переменных, которые мы и будем использовать (а нас, собственно, интересует только одна — auth_hash). Ищем нужные значения.
- Снова отправляем запрос на тот же адрес, что и в первом пункте, но теперь на забываем указать полученное значение auth_hash.
Теперь подробнее:
Шаг 1.
Отправляем запрос на адрес http://vk.com/login.php и передаем следующие параметры:
| email | Адрес эл. почты пользователя | pass | Его пароль от ВК |
NSURL *url = [NSURL URLWithString:
[NSString stringWithFormat:@"http://vk.com/login.php?email=%@&pass=%@",
EMAIL,
PASSWORD]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSData *empty_request = [NSURLConnection sendSynchronousRequest: request
returningResponse: nil
error: nil];
Шаг 2.
Далее, нам нужно получить исходный код все той же страницы авторизации(http://vk.com/login.php), но уже с другими параметрами:
| app | ID вашего приложения | layout | Тип дизайна страницы авторизации | type | Способ передачи значение сессии | settings | Требуемые права доступа |
layout и type — стандартные параметры, их менять не стоит.
Затем, в HTML-коде ищем значение переменной auth_hash.
// Получаем исходный код страницы
NSString *stringURL = [NSString stringWithFormat:@"http://vk.com/login.php?app=%@&layout=popup&type=browser&settings=%@",
api_id,
settings];
NSURL *url = [NSURL URLWithString:stringURL];
NSRequest *request = [NSURLRequest requestWithURL:url];
NSData *raw_data = [NSURLConnection sendSynchronousRequest: request
returningResponse:nil
error:nil];
NSString *pageSource = [[NSString alloc] initWithData:raw_data encoding: NSASCIIStringEncoding];
// Ищем переменную auth_hash
// Реализация функции getStringBetweenStrings - в прилагаемом исходном файле
NSString *auth_hash = getStringBetweenStrings(@"var auth_hash = \'",@"\';",pageSource);
Шаг 3
И снова отправляем запрос на авторизацию. Там все понятно — приведу только пример кода.
NSString *string = [NSString stringWithFormat:
@"http://vk.com/login.php?act=a_auth&app=%@&hash=%@&permanent=1",
api_id,
auth_hash];
NSURL *url = [NSURL urlWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSData *tempContainer = [NSURLConnection sendSynchronousRequest: request
returningResponse:nil
error:nil];
tempContainer — объект с параметрами сесии в виде JSON строки. Распарсить его можно, например, при помощи JSONKit:
#import "JSONKit.h"
JSONDecoder *decoder = [JSONDecoder decoder];
NSDictionary *params = [decoder parseJSONData:tempContainer];
Вот и весь процесс авторизации. В любом случае, рекомендую прочитать оригинальную статью про авторизацию Desktop-приложений ВКонтакте.
В следующей части статьи будет рассмотрено непосредственно взаимодействие с API ВКонтакте.
Файлы статьи
Ресурсы
Объясните, пожалуйста, почему так: когда я запускаю ваш пример, то все работает правильно и в конце я получаю строку с параметрами сессии. Но когда я запускаю ваш пример в iPhone симуляторе, то в конце ( получаем нужную строку адреса
NSString *redirect_path = [[responce URL] absoluteString]), в переменной redirect_path лежит не ссылка на которую происходит редирект, а ссылка которую я открывал: vkontakte.ru/login.php?app=ID_OF_YOUR_APP&layout=popup&type=browser&remixsid=ПЕРЕМЕННАЯ_S//
Да, был такой баг. Сложно сказать, почему там оно происходит.
Статью обновил — попробуйте новым способом.
Пожалуста, отремонтируйте вот эту ссылку: (Пример того, как это можно сделать — метод dictionaryFromParsingAgruments из прилагаемого проекта).
Доброго времени суток.
Не могли бы вы мне помочь, пожалуйста? При отправке запроса на права приложения, они, почему то, не даются:
NSURL *new_url = [NSURL URLWithString:[NSString stringWithFormat:@«vk.com/login.php?app=%@&layout=popup&type=browser&settings=15615", sAPI_ID]];"
После перехода по следующей ссылке:
[NSURL URLWithString:[NSString stringWithFormat:@«vk.com/login.php?act=a_auth&app=%@&hash=%@&permanent=1",sAPI_ID,Auth_Hash]"
Мне корректно возвращается mid, sid, secret, expire, sig.