Обход ограничений desktop для PHP-скриптов

Создание Desktop-приложений, виджеты ВКонтакте для сайтов и публичных страниц, OAuth 2.0, Open API, Standalone
Ответить
Ensiferum
Сообщения: 4
Зарегистрирован: 24 мар 2011, 08:05

Обход ограничений desktop для PHP-скриптов

Сообщение Ensiferum »

Часть API (расширенная) доступна только desktop-скриптам. Решил обойти это ограничение:

Код: Выделить всё

<?php   class vkapi {     public $mid                = '';     public $sid                = '';     public $secret            = '';     public $expire            = '';     public $settings        = '';     public $settings_hash    = '';     public $user_first_name = '';     public $user_full_name    = '';     public $user_thumb        = '';     public $auth_hash        = '';     public $sig                = '';     private $api_id            = '';     public $cookie            = '';        // печеньки     public $remixsid        = '';        // главная печенька     public $antigateHash    = '';          public function __construct($api_id='') {         $this->api_id = $api_id;     }          public function get($url, $follow=1) {         $process = curl_init($url);         curl_setopt($process, CURLOPT_HEADER, 1);         curl_setopt($process, CURLOPT_USERAGENT, 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; ru-ru) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7');         curl_setopt($process, CURLOPT_COOKIE,$this->cookie);         curl_setopt($process, CURLOPT_TIMEOUT, 15);         curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);         curl_setopt($process, CURLOPT_FOLLOWLOCATION, $follow);           $return = curl_exec($process);         curl_close($process);         return $return;     }       public function post($url, $data, $follow=1) {         $process = curl_init($url);         curl_setopt($process, CURLOPT_HEADER, 1);         curl_setopt($process, CURLOPT_USERAGENT, 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; ru-ru) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7');         curl_setopt($process, CURLOPT_COOKIE,$this->cookie);         curl_setopt($process, CURLOPT_TIMEOUT, 15);         curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);         curl_setopt($process, CURLOPT_FOLLOWLOCATION, $follow);         curl_setopt($process, CURLOPT_POST, 1);         curl_setopt($process, CURLOPT_POSTFIELDS, $data);                   $return = curl_exec($process);         curl_close($process);         return $return;     }         public function doAppPermit() {         /* Возвращается объект со следующими значениями:         expire    Время истечения сессии в формате UNIX          mid    ID пользователя в ВКонтакте          secret    Специально сгенерированный секрет сессии          sid    Идентификатор сессии         */         $resp = $this->getBody($this->post('http://vkontakte.ru/login.php', 'act=a_auth&app='.$this->api_id.'&hash='.$this->auth_hash.'&permanent=1'));         if ($obj = @json_decode($resp)) {             $this->mid        = $obj->mid;             $this->sid        = $obj->sid;             $this->secret    = $obj->secret;             $this->expire    = $obj->expire;         } else return false;     }          public function doLogin($login, $pass) {         // 1 шаг         $resp = $this->post('http://vkontakte.ru/login.php?app='.$this->api_id.'&layout=popup&type=browser&settings=16383', '',1);         $this->getCookie($resp);         $match = array();         preg_match('#type=("|\')hidden("|\')\sname=("|\')app_hash("|\')\svalue=("|\')(.*)("|\')#Us', $resp, $match[]);         preg_match('#type=("|\')hidden("|\')\sname=("|\')vk("|\')\svalue=("|\')(.*)("|\')#Us', $resp, $match[]);         preg_match('#type=("|\')hidden("|\')\sname=("|\')permanent("|\')\svalue=("|\')(.*)("|\')#Us', $resp, $match[]);         preg_match('#type=("|\')hidden("|\')\sname=("|\')al_test("|\')\svalue=("|\')(.*)("|\')#Us', $resp, $match[]);           $postdata = "act=login&app={$this->api_id}&app_hash={$match[0][6]}&vk={$match[1][6]}&captcha_sid=&al_test={$match[3][6]}&captcha_key=&email={$login}&pass={$pass}&expire=&permanent={$match[2][6]}";           // 2 Шаг         $resp = $this->post('http://login.vk.com/', $postdata, 0);         $this->cookie = '';         $this->getCookie($resp);           if (preg_match_all('#name=("|\')(.*)("|\')\svalue=("|\')(.*)("|\')#Us', $resp, $match)) {             $postdata = '';                      foreach ($match[2] as $k => $v) {                 $postdata .= $match[2][$k] . '=' . $match[5][$k] . '&';             }             $postdata = substr($postdata, 0, -1);                          preg_match('#name=("|\')s("|\')\svalue=("|\')(.*)("|\')#Us', $resp, $match);             $this->remixsid = $match[4];                          // 3 Шаг             $resp = $this->post('http://vkontakte.ru/login.php', $postdata, 0);               if (preg_match('#<script type="text/javascript">parent.onDone\((.*)\)<\/script>#Us', $resp, $match)) {                 $obj = json_decode(iconv("WINDOWS-1251", "UTF-8", $match[1]));                 $this->mid                = $obj->mid;                 $this->sid                = $obj->sid;                 $this->secret            = $obj->secret;                 $this->expire            = $obj->expire;                 $this->settings        = $obj->settings;                 $this->settings_hash    = $obj->settings_hash;                 $this->user_first_name    = $obj->user_first_name;                 $this->user_full_name    = $obj->user_full_name;                 $this->user_thumb        = $obj->user_thumb;                 $this->auth_hash        = $obj->auth_hash;                   return true;             } else return false;         } else return false;     }          public function desktop_api($method, $data='') {         $sig = '';                  $postdata = array(             'api_id'    => $this->api_id,             'v'            => '3.0',             'format'    => 'JSON',             'method'    => $method         );                  if ($data) {             foreach ($data as $k => $v) {                     $postdata[$k] = $v;             }         }         ksort($postdata, SORT_STRING);           foreach ($postdata as $k => $v)             $sig .= $k . '=' . $v;                  $sig = md5($this->mid . $sig . $this->secret);                   $postdata['sig'] = $sig;         $postdata['sid'] = $this->sid;           $resp = $this->post('http://api.vkontakte.ru/api.php', $postdata);         return $resp;     }       public function saveSettings() {         $this->cookie = "remixchk=5; remixsid=".$this->remixsid;           $postdata = array('addMember' => 1, 'id' => $this->api_id, 'hash' => $this->settings_hash, 'app_settings_8192' => 1, 'app_settings_4096' => 1,'app_settings_2048' => 1,'app_settings_1024' => 1,'app_settings_512' => 1,'app_settings_256' => 1,'app_settings_128' => 1,'app_settings_64' => 1,'app_settings_32' => 1,'app_settings_16' => 1,'app_settings_8' => 1);         $resp = $this->post('http://vkontakte.ru/apps.php?act=a_save_settings', $postdata, 1);                      // Работаем с капчей         if (preg_match('#"captcha_sid":"(.*)"#Us', $resp, $match)) {             if ($this->antigateHash) {                 $temp = $this->getBody($this->get('http://m.vkontakte.ru/captcha?s=1&sid='.$match[1]));                   file_put_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'captcha'. DIRECTORY_SEPARATOR . $match[1].'.jpg',$temp);                 $temp = $this->captcha(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'captcha'. DIRECTORY_SEPARATOR . $match[1].'.jpg');                                  $postdata['captcha_sid'] = $match[1];                 $postdata['captcha_key'] = $temp;                                  $resp = $this->post('http://vkontakte.ru/apps.php?act=a_save_settings', $postdata, 1);             } else {                 return false;             }             } else {             return true;         }     }          // Достаем из запроса кукисы     private function getCookie($data) {         if (preg_match_all('#Set-Cookie: (.*);#Us',$data,$match))             $this->cookie .= implode('; ',$match[1]);     }              // Возвращает текст ответа сервера без заголовка     public function getBody($text) {         return array_pop(explode(PHP_EOL.PHP_EOL,$text));     }       public function captcha($captchaFile) {         $rtimeout = 5;         $mtimeout = 90;         $postdata = array(             'method'    => 'post',             'key'      => $this->antigateHash,             'file'      => '@'.$captchaFile,             'phrase'    => 0,             'regsense'    => 1,             'numeric'    => 0,             'min_len'    => 4,             'max_len'    => 7         );           $result =  $this->post('http://www.antigate.com/in.php', $postdata);           if (strpos($result, "ERROR")!==false) {             $this->captchaDebug = $this->getBody($result);             return false;         }         else {             $ex = explode("|", $result);             $captcha_id = $ex[1];             $waittime = 0;             sleep($rtimeout);             $time1 = microtime(true);             while(true) {                 $result = @file_get_contents('http://antigate.com/res.php?key='.$this->antigateHash.'&action=get&id='.$captcha_id);                 if (strpos($result, 'ERROR')!==false) {                     $this->captchaDebug = $result;                     return false;                 }                 if ($result=="CAPCHA_NOT_READY") {                     $waittime += $rtimeout;                     if ($waittime>$mtimeout) {                         $this->captchaDebug = 'Time expired';                         break;                     }                     sleep($rtimeout);                 }                 else {                     $ex = explode('|', $result);                     if (trim($ex[0])=='OK') {                         $this->captchaTime = microtime(true) - $time1;                         return trim($ex[1]);                     }                 }             }             return false;         }     }     } ?>
применение класса:

Код: Выделить всё

<?php $api_id = '111111'; $login    = 'asd@asd.ru'; $pass    = 'qwe';   $vk = new vkapi($api_id);   if ($vk->doLogin($login, $pass)) {     $vk->saveSettings();     $vk->doAppPermit();                  $text = $vk->getBody($vk->desktop_api('newsfeed.get', ''));     echo $text; } ?>
Смысл: скрипт по логину-паролю пользователя добавляет ему приложение со всеми правами. Скрипт поддерживает капчи с antigate.com.
Ответить