VkontakteAPI. Разбор полётов.
Запись от VitaliyKrivtsov размещена 18.05.2011 в 23:48
Обновил(-а) VitaliyKrivtsov 25.06.2011 в 22:27
Обновил(-а) VitaliyKrivtsov 25.06.2011 в 22:27
Эта статья будет интересна тем, кому хотелось бы знать, как работать с ВконтактеAPI, так сказать, на "низком уровне", без посредника:
- APIConnection для взаимодействия с API без контейнера;
- Wrapper для взаимодействия с API с использованием контейнера;
Рассматривается отправка запроса для получения от Вконтакте данных, касающейся пользователя приложения.
Разобравшись с тем, как работать с ВконтактеAPI можно написать собственную библиотеку, так как APIConnection предоставляет из себя инструмент для отправки запросов и кое-какой обработки ответа, а этого мало. Для взаимодействия с JavaScript API без APIConnection и Wrapper не обойтись. По этому написать приложение не прибегая к использованию посредника, не получится, но нам и не нужно - главное понять, как осуществлять запросы к API.
Скорей всего, старожилам, которые грызут API Вконтакте уже не первый месяц, статья не понадобится, то бишь статься ориентирована на новичков.
В посте рассматривается взаимодействие по таким схемам:
- API2.0 (в данный момент не актуально, но знать особенности - полезно);
- API3.0;
- OAuth2.0(к сегодняшнему дню статус - beta, но тем не менее - работает отлично);
Начнем
Очень недавно Вконтакте (где-то полтора месяца назад) переделали раздел "Мои приложения", в частности и интерфейс админки приложения. Как оказалось - не без последствий для разработчиков. Убрали secret, который можно было применять для подписывания сигнатуры по старой схеме взаимодействия - API 2.0. Неприятное, то что убрать то убрали, но не написали в документации, что искать secret в настройках приложения не стоит, так как его там уже давно нет. И так, этот secret нужен был для подписи сигнатуры по API 2.0, но не для API 3.0. После небольших изменений в схеме взаимодействия API 2.0 - разработчики ВконтактеAPI решили обозвать его API 3.0.
Взаимодействие приложения с API по схеме API 3.0
Что нового появилось в API 3.0:
1. secret, который мы получаем flashVars использовать можно исключительно по схеме - API 3.0;
2. sid - идентификатор сессии. Получить можно только из flashVars. Передается посредством POST/GET запроса серверу как переменная с остальными параметрами конкретного метода API (если таковые есть);
3. v=3.0 - версия используемого API.
Что бы осуществить запрос по схеме API 3.0 нужно обязательно передавать sid. В формировании сигнатуры - sid не нужно использовать. Рассмотрим формирование запроса и в частности сигнатуры на примере метода getProfiles. Укажем параметры, которые нас интересуют - nickname, sex, bdate. В результате успешного запроса, сервер возвращает uid, first_name, last_name - всегда, даже если не указали явно и nickname, sex, bdate при условии, что эти поля у пользователя заполнены.
Обязательными параметрами запроса есть id приложения, method, sid согласно документации. Но здесь упущен один важный параметр. Согласно доков параметр v не есть обязательным и по умолчанию равен 3.0. Если упустить этот параметр - получаем в ответ ошибку:
<?xml version="1.0" encoding="utf-8"?> <error>Incorrect signature: server authorization</error>
var arr:Array = []; arr.push( "api_id="+api_id ); arr.push( "format=XML" ); arr.push( "v=3.0" ); arr.push( "method=getProfiles" ); arr.push( "uids="+viewer_id ); arr.push( "fields=nickname,bdate,sex" ); arr.sort( );
Параметр sig равен md5 от контактенации:
- viewer_id;
- параметры запроса;
- secret;
То есть:
Добавляем sig и sid в параметры запроса:
var arr:Array = []; arr.push( "api_id="+api_id ); arr.push( "format=XML" ); arr.push( "v=3.0" ); arr.push( "method=getProfiles" ); arr.push( "uids="+viewer_id ); arr.push( "fields=nickname,bdate,sex" ); // -- // arr.sort( ); // -- // var sig:String = MD5.hash( viewer_id + arr.join("") + secret ); arr.push( "sig=" + sig ); arr.push( "sid=" + sid );
var req:String = arr.join( "&" ); // -- // var urlLoader:URLLoader = new URLLoader( ); var urlRequest:URLRequest = new URLRequest( ); urlRequest.url = "http://api.vkontakte.ru/api.php"; var urlVariables:URLVariables = new URLVariables( req ); urlRequest.method = "POST"; urlRequest.data = urlVariables; urlLoader.load( urlRequest ); urlLoader.addEventListener( Event.COMPLETE, completeHandler );
package example { import by.blooddy.crypto.MD5; import flash.display.Sprite; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLRequest; import flash.net.URLVariables; /** * ... * @author Vitalik Krivtsov aka Nickel */ public class Example extends Sprite { /** * @private * id приложения. */ private var api_id:String = "2192563"; /** * @private * id пользователя. */ private var viewer_id:String = "41138144"; /** * @private * идентификатор сессии. */ private var sid:String = "0eb7159b2e2273f75df88caa440eda4cfc9b1cafa39aa27c4dc83173eb889d"; /** * @private * секрет приложения. */ private var secret:String = "0a8d203358"; public function Example() { var arr:Array = []; arr.push( "api_id="+api_id ); arr.push( "format=XML" ); arr.push( "v=3.0" ); arr.push( "method=getProfiles" ); arr.push( "uids="+viewer_id ); arr.push( "fields=nickname,bdate,sex" ); // -- // arr.sort( ); // -- // var sig:String = MD5.hash( viewer_id + arr.join("") + secret ); arr.push( "sig=" + sig ); arr.push( "sid=" + sid ); var req:String = arr.join( "&" ); // -- // var urlLoader:URLLoader = new URLLoader( ); var urlRequest:URLRequest = new URLRequest( "http://api.vkontakte.ru/api.php" ); var urlVariables:URLVariables = new URLVariables( req ); urlRequest.method = "POST"; urlRequest.data = urlVariables; urlLoader.load( urlRequest ); urlLoader.addEventListener( Event.COMPLETE, completeHandler ); } private function completeHandler( event:Event ):void { trace( event.target.data ); } } }
<?xml version="1.0" encoding="utf-8"?> <response list="true"> <user> <uid>41138144</uid> <first_name>Виталий</first_name> <last_name>Кривцов</last_name> <nickname>Nickel</nickname> <bdate>21.5.1992</bdate> <sex>2</sex> </user> </response>
Все пройдет успешно. Если не задать параметр или передать test_mode равным 0, то получим следующую ошибку:
<?xml version="1.0" encoding="utf-8"?> <error> <error_code>2</error_code> <error_msg>Application is disabled. Enable your application or use test mode</error_msg> <request_params list="true"> <param> <key>sid</key> <value>ecf4bb724f628819831bfb14f7fc7cd790e1218dd5212f4fb6c59a4aa3f815</value> </param> <param> <key>format</key> <value>XML</value> </param> <param> <key>sig</key> <value>ffc077d5ae4336618a07424b162cb2c7</value> </param> <param> <key>uids</key> <value>41138144</value> </param> <param> <key>method</key> <value>getProfiles</value> </param> <param> <key>fields</key> <value>nickname,bdate,sex</value> </param> <param> <key>api_id</key> <value>2192563</value> </param> <param> <key>v</key> <value>3.0</value> </param> </request_params> </error>
<?xml version="1.0" encoding="utf-8"?> <error> <error_code>11</error_code> <error_msg>In test mode application should be disabled or user should be authorized</error_msg> <request_params list="true"> <param> <key>sid</key> <value>ecf4bb724f628819831bfb14f7fc7cd790e1218dd5212f4fb6c59a4aa3f815</value> </param> <param> <key>test_mode</key> <value>1</value> </param> <param> <key>uids</key> <value>41138144</value> </param> <param> <key>format</key> <value>XML</value> </param> <param> <key>sig</key> <value>883d675957759cc2cd42b7d814bd3ef7</value> </param> <param> <key>method</key> <value>getProfiles</value> </param> <param> <key>fields</key> <value>nickname,bdate,sex</value> </param> <param> <key>api_id</key> <value>2192563</value> </param> <param> <key>v</key> <value>3.0</value> </param> </request_params> </error>
Добавлять в массив с параметрами нужно до сортировки элементов, то есть этот параметр участвует в формировании сигнатуры. И так, мы очень подробно разобрали формирование запроса по схеме API 3.0.
Теперь можно приступить к API 2.0.
Взаимодействие приложения с API по схеме API 2.0
Собственно разжёвывать тут ничего не нужно, все происходит точно так же как и в API 3.0. Но все же сделаю акцент на следующих моментах. Для формирования сигнатуры нужен ключ со страницы редактирования приложения - но его убрали по этому воспользоватся этой схемой не получится и не стоит читать документацию по API 2.0, лучше взяться за API 3.0. Приведу код, да бы пролить свет на их различия, а их немного:
package example { import by.blooddy.crypto.MD5; import flash.display.Sprite; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLRequest; import flash.net.URLVariables; /** * ... * @author Vitalik Krivtsov aka Nickel */ public class Example extends Sprite { /** * @private * id приложения. */ private var api_id:String = "2192563"; /** * @private * id пользователя. */ private var viewer_id:String = "41138144"; /** * @private * секрет приложения. */ private var secret:String = "e5c2568b77"; public function Example() { var arr:Array = []; arr.push( "api_id="+api_id ); arr.push( "format=XML" ); arr.push( "v=2.0" ); arr.push( "method=getProfiles" ); arr.push( "uids="+viewer_id ); arr.push( "fields=nickname,bdate,sex" ); // -- // arr.sort( ); // -- // var sig:String = MD5.hash( viewer_id + arr.join("") + secret ); arr.push( "sig=" + sig ); var req:String = arr.join( "&" ); var urlVariables:URLVariables = new URLVariables( req ); // -- // var urlRequest:URLRequest = new URLRequest( ); urlRequest.url = "http://api.vkontakte.ru/api.php"; urlRequest.method = "POST"; urlRequest.data = urlVariables; var urlLoader:URLLoader = new URLLoader( ); urlLoader.load( urlRequest ); urlLoader.addEventListener( Event.COMPLETE, completeHandler ); } private function completeHandler( event:Event ):void { trace( event.target.data ); } } }
Взаимодействие приложения с API по схеме OAuth 2.0
При использовании этой схеме геморроя гораздо меньше, а значит сделать ошибку в запросе становится в разы тяжелее.
Согласно документации наш запрос представляет из себя следующее:
var urL:String = "https://api.vkontakte.ru/method/getProfiles?uids=41138144&fields=nickname,bdate,sex&access_token=1bdf17ea54578cce19f114e1b1198dd4b9e19ad19ac8ef5898c0bc2f31db472";
{"response":[ {"uid":41138144, "first_name":"Виталий", "last_name":"Кривцов", "nickname":"Nickel", "bdate":"21.5.1992", "sex":"2"} ]}
package example { import by.blooddy.crypto.MD5; import flash.display.Sprite; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLRequest; import flash.net.URLVariables; /** * ... * @author Vitalik Krivtsov aka Nickel */ public class Example extends Sprite { public function Example() { if (stage) init(); else addEventListener( Event.ADDED_TO_STAGE, init ); } private function init( event:Event = null ):void { var flashVars:Object = stage.loaderInfo.parameters as Object; var urlVariables:URLVariables = new URLVariables(); urlVariables.access_token = flashVars.access_token; urlVariables.fields = "nickname, bdate, sex"; urlVariables.uids = flashVars.viewer_id; var urlRequest:URLRequest = new URLRequest( ); urlRequest.url = "https://api.vkontakte.ru/method/getProfiles"; urlRequest.method = "POST"; urlRequest.data = urlVariables; var urlLoader:URLLoader = new URLLoader( ); urlLoader.load( urlRequest ); urlLoader.addEventListener( Event.COMPLETE, completeHandler ); } private function completeHandler( event:Event ):void { trace( event.target.data ); } } }
Собственно, рассмотрены всевозможные варианты взаимодействия с сервером ВКонтакте. Теперь на пути к написанию приложения одним вопросом стало меньше.
Всего комментариев 5
Комментарии
26.05.2011 21:43 | |
Ой как в тему. Спасибо.
|
26.05.2011 22:24 | |
Если приложение отключено, то test_mode необходим в 3 версии
|
26.05.2011 23:12 | |
Цитата:
Если приложение отключено, то test_mode необходим в 3 версии
Если приложение выключено и передан параметр test_mode со значением 1 - сервер вернет ошибку: <?xml version="1.0" encoding="utf-8"?> <error> <error_code>2</error_code> <error_msg>Application is disabled. Enable your application or use test mode</error_msg> <request_params list="true"> <param> <key>api_id</key> <value>2192563</value> </param> <param> <key>fields</key> <value>nickname,bdate,sex</value> </param> <param> <key>format</key> <value>XML</value> </param> <param> <key>method</key> <value>getProfiles</value> </param> <param> <key>sid</key> <value>b8c259a95b4a34fcdd04e2a9880d2a7fd56dc819b49f8f779c5471b0d8547d</value> </param> <param> <key>sig</key> <value>9f7584c1f6d442e911738d85fcbf459f</value> </param> <param> <key>uids</key> <value>41138144</value> </param> <param> <key>v</key> <value>3.0</value> </param> </request_params> </error> Если приложение включено, secret и sid свежие и при этом передали в переменных запроса test_mode - параметр проигнорируется. |
|
Обновил(-а) VitaliyKrivtsov 26.05.2011 в 23:22
|
Последние записи от VitaliyKrivtsov
- NameCaseLib. Склонение фамилии, имени и отчества (04.12.2011)
- Шаблон проекта для as3vkontaktelib под FlashDevelop (27.08.2011)
- Обновление as3vkontaktelib до версии .-90 (13.08.2011)
- VkontakteAPI. Разбор полётов. (18.05.2011)
- Библиотека для взаимодействия с Вконтакте API (11.03.2011)