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

Создание Desktop-приложений, виджеты ВКонтакте для сайтов и публичных страниц, OAuth 2.0, Open API, Standalone

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

Сообщение Ensiferum » 24 мар 2011, 08:12

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

  1. <?php
  2.  
  3.  class vkapi {
  4.      public $mid                = '';
  5.      public $sid                = '';
  6.      public $secret            = '';
  7.      public $expire            = '';
  8.      public $settings        = '';
  9.      public $settings_hash    = '';
  10.      public $user_first_name = '';
  11.      public $user_full_name    = '';
  12.      public $user_thumb        = '';
  13.      public $auth_hash        = '';
  14.      public $sig                = '';
  15.      private $api_id            = '';
  16.      public $cookie            = '';        // печеньки
  17.      public $remixsid        = '';        // главная печенька
  18.      public $antigateHash    = '';
  19.      
  20.      public function __construct($api_id='') {
  21.          $this->api_id = $api_id;
  22.      }
  23.      
  24.      public function get($url, $follow=1) {
  25.          $process = curl_init($url);
  26.          curl_setopt($process, CURLOPT_HEADER, 1);
  27.          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');
  28.          curl_setopt($process, CURLOPT_COOKIE,$this->cookie);
  29.          curl_setopt($process, CURLOPT_TIMEOUT, 15);
  30.          curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
  31.          curl_setopt($process, CURLOPT_FOLLOWLOCATION, $follow);
  32.  
  33.          $return = curl_exec($process);
  34.          curl_close($process);
  35.          return $return;
  36.      }
  37.  
  38.      public function post($url, $data, $follow=1) {
  39.          $process = curl_init($url);
  40.          curl_setopt($process, CURLOPT_HEADER, 1);
  41.          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');
  42.          curl_setopt($process, CURLOPT_COOKIE,$this->cookie);
  43.          curl_setopt($process, CURLOPT_TIMEOUT, 15);
  44.          curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
  45.          curl_setopt($process, CURLOPT_FOLLOWLOCATION, $follow);
  46.          curl_setopt($process, CURLOPT_POST, 1);
  47.          curl_setopt($process, CURLOPT_POSTFIELDS, $data);        
  48.  
  49.          $return = curl_exec($process);
  50.          curl_close($process);
  51.          return $return;
  52.      }    
  53.      public function doAppPermit() {
  54.          /* Возвращается объект со следующими значениями:
  55.          expire    Время истечения сессии в формате UNIX
  56.          mid    ID пользователя в ВКонтакте
  57.          secret    Специально сгенерированный секрет сессии
  58.          sid    Идентификатор сессии
  59.          */
  60.          $resp = $this->getBody($this->post('http://vkontakte.ru/login.php', 'act=a_auth&app='.$this->api_id.'&hash='.$this->auth_hash.'&permanent=1'));
  61.          if ($obj = @json_decode($resp)) {
  62.              $this->mid        = $obj->mid;
  63.              $this->sid        = $obj->sid;
  64.              $this->secret    = $obj->secret;
  65.              $this->expire    = $obj->expire;
  66.          } else return false;
  67.      }
  68.      
  69.      public function doLogin($login, $pass) {
  70.          // 1 шаг
  71.          $resp = $this->post('http://vkontakte.ru/login.php?app='.$this->api_id.'&layout=popup&type=browser&settings=16383', '',1);
  72.          $this->getCookie($resp);
  73.          $match = array();
  74.          preg_match('#type=("|')hidden("|')\sname=("|')app_hash("|')\svalue=("|')(.*)("|')#Us', $resp, $match[]);
  75.          preg_match('#type=("|')hidden("|')\sname=("|')vk("|')\svalue=("|')(.*)("|')#Us', $resp, $match[]);
  76.          preg_match('#type=("|')hidden("|')\sname=("|')permanent("|')\svalue=("|')(.*)("|')#Us', $resp, $match[]);
  77.          preg_match('#type=("|')hidden("|')\sname=("|')al_test("|')\svalue=("|')(.*)("|')#Us', $resp, $match[]);
  78.  
  79.          $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]}";
  80.  
  81.          // 2 Шаг
  82.          $resp = $this->post('http://login.vk.com/', $postdata, 0);
  83.          $this->cookie = '';
  84.          $this->getCookie($resp);
  85.  
  86.          if (preg_match_all('#name=("|')(.*)("|')\svalue=("|')(.*)("|')#Us', $resp, $match)) {
  87.              $postdata = '';
  88.          
  89.              foreach ($match[2] as $k => $v) {
  90.                  $postdata .= $match[2][$k] . '=' . $match[5][$k] . '&';
  91.              }
  92.              $postdata = substr($postdata, 0, -1);
  93.              
  94.              preg_match('#name=("|')s("|')\svalue=("|')(.*)("|')#Us', $resp, $match);
  95.              $this->remixsid = $match[4];
  96.              
  97.              // 3 Шаг
  98.              $resp = $this->post('http://vkontakte.ru/login.php', $postdata, 0);
  99.  
  100.              if (preg_match('#<script type="text/javascript">parent.onDone\((.*)\)<\/script>#Us', $resp, $match)) {
  101.                  $obj = json_decode(iconv("WINDOWS-1251", "UTF-8", $match[1]));
  102.                  $this->mid                = $obj->mid;
  103.                  $this->sid                = $obj->sid;
  104.                  $this->secret            = $obj->secret;
  105.                  $this->expire            = $obj->expire;
  106.                  $this->settings        = $obj->settings;
  107.                  $this->settings_hash    = $obj->settings_hash;
  108.                  $this->user_first_name    = $obj->user_first_name;
  109.                  $this->user_full_name    = $obj->user_full_name;
  110.                  $this->user_thumb        = $obj->user_thumb;
  111.                  $this->auth_hash        = $obj->auth_hash;
  112.  
  113.                  return true;
  114.              } else return false;
  115.          } else return false;
  116.      }
  117.      
  118.      public function desktop_api($method, $data='') {
  119.          $sig = '';
  120.          
  121.          $postdata = array(
  122.              'api_id'    => $this->api_id,
  123.              'v'            => '3.0',
  124.              'format'    => 'JSON',
  125.              'method'    => $method
  126.          );
  127.          
  128.          if ($data) {
  129.              foreach ($data as $k => $v) {
  130.                      $postdata[$k] = $v;
  131.              }
  132.          }
  133.          ksort($postdata, SORT_STRING);
  134.  
  135.          foreach ($postdata as $k => $v)
  136.              $sig .= $k . '=' . $v;
  137.          
  138.          $sig = md5($this->mid . $sig . $this->secret);        
  139.  
  140.          $postdata['sig'] = $sig;
  141.          $postdata['sid'] = $this->sid;
  142.  
  143.          $resp = $this->post('http://api.vkontakte.ru/api.php', $postdata);
  144.          return $resp;
  145.      }
  146.  
  147.      public function saveSettings() {
  148.          $this->cookie = "remixchk=5; remixsid=".$this->remixsid;
  149.  
  150.          $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);
  151.          $resp = $this->post('http://vkontakte.ru/apps.php?act=a_save_settings', $postdata, 1);    
  152.          
  153.          // Работаем с капчей
  154.          if (preg_match('#"captcha_sid":"(.*)"#Us', $resp, $match)) {
  155.              if ($this->antigateHash) {
  156.                  $temp = $this->getBody($this->get('http://m.vkontakte.ru/captcha?s=1&sid='.$match[1]));
  157.  
  158.                  file_put_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'captcha'. DIRECTORY_SEPARATOR . $match[1].'.jpg',$temp);
  159.                  $temp = $this->captcha(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'captcha'. DIRECTORY_SEPARATOR . $match[1].'.jpg');
  160.                  
  161.                  $postdata['captcha_sid'] = $match[1];
  162.                  $postdata['captcha_key'] = $temp;
  163.                  
  164.                  $resp = $this->post('http://vkontakte.ru/apps.php?act=a_save_settings', $postdata, 1);
  165.              } else {
  166.                  return false;
  167.              }    
  168.          } else {
  169.              return true;
  170.          }
  171.      }
  172.      
  173.      // Достаем из запроса кукисы
  174.      private function getCookie($data) {
  175.          if (preg_match_all('#Set-Cookie: (.*);#Us',$data,$match))
  176.              $this->cookie .= implode('; ',$match[1]);
  177.      }    
  178.      
  179.      // Возвращает текст ответа сервера без заголовка
  180.      public function getBody($text) {
  181.          return array_pop(explode(PHP_EOL.PHP_EOL,$text));
  182.      }
  183.  
  184.      public function captcha($captchaFile) {
  185.          $rtimeout = 5;
  186.          $mtimeout = 90;
  187.          $postdata = array(
  188.              'method'    => 'post',
  189.              'key'      => $this->antigateHash,
  190.              'file'      => '@'.$captchaFile,
  191.              'phrase'    => 0,
  192.              'regsense'    => 1,
  193.              'numeric'    => 0,
  194.              'min_len'    => 4,
  195.              'max_len'    => 7
  196.          );
  197.  
  198.          $result =  $this->post('http://www.antigate.com/in.php', $postdata);
  199.  
  200.          if (strpos($result, "ERROR")!==false) {
  201.              $this->captchaDebug = $this->getBody($result);
  202.              return false;
  203.          }
  204.          else {
  205.              $ex = explode("|", $result);
  206.              $captcha_id = $ex[1];
  207.              $waittime = 0;
  208.              sleep($rtimeout);
  209.              $time1 = microtime(true);
  210.              while(true) {
  211.                  $result = @file_get_contents('http://antigate.com/res.php?key='.$this->antigateHash.'&action=get&id='.$captcha_id);
  212.                  if (strpos($result, 'ERROR')!==false) {
  213.                      $this->captchaDebug = $result;
  214.                      return false;
  215.                  }
  216.                  if ($result=="CAPCHA_NOT_READY") {
  217.                      $waittime += $rtimeout;
  218.                      if ($waittime>$mtimeout) {
  219.                          $this->captchaDebug = 'Time expired';
  220.                          break;
  221.                      }
  222.                      sleep($rtimeout);
  223.                  }
  224.                  else {
  225.                      $ex = explode('|', $result);
  226.                      if (trim($ex[0])=='OK') {
  227.                          $this->captchaTime = microtime(true) - $time1;
  228.                          return trim($ex[1]);
  229.                      }
  230.                  }
  231.              }
  232.              return false;
  233.          }
  234.      }    
  235.  }
  236.  ?>


применение класса:

  1. <?php
  2.  $api_id = '111111';
  3.  $login    = 'asd@asd.ru';
  4.  $pass    = 'qwe';
  5.  
  6.  $vk = new vkapi($api_id);
  7.  
  8.  if ($vk->doLogin($login, $pass)) {
  9.      $vk->saveSettings();
  10.      $vk->doAppPermit();
  11.              
  12.      $text = $vk->getBody($vk->desktop_api('newsfeed.get', ''));
  13.      echo $text;
  14.  }
  15.  ?>


Смысл: скрипт по логину-паролю пользователя добавляет ему приложение со всеми правами. Скрипт поддерживает капчи с antigate.com.

За это сообщение автора Ensiferum поблагодарили - 2:
Noise Gate, psix55
Ensiferum

 
Автор темы
Сообщения: 4
Зарегистрирован: 24 мар 2011, 08:05
Благодарил (а): 0 раз.
Поблагодарили: 2 раз.

Чтобы убрать блок с рекламой, зарегистрируйтесь на форуме или войдите.

Google
 



Вернуться в Desktop-приложения, виджеты ВКонтакте, OAuth



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

cron