Ответы пользователя по тегу ВКонтакте
  • Как лучше вытащить access_token в VK?

    > Как выдернуть access_token и закрыть окно что бы человек не заморачивался с ручным копированием access_token ?
    > Может быть есть другие способы его получения?
    Я сделал возможность автоматического копирования токена.
    Суть в том что вы собираете заголовки всех 3 запросов:
    1. запрос где указан cliend_id, scope и redirect_uri, возвращает Location на второй запрос
    2. второй запрос вернет Location на redirect_uri, вот в нем и будет наш access_token.
    3. Заголовок к вашему redirect_uri.
    Дальше обычной регуляркой вытаскиваете Location из третьего запроса. Примерно это выглядит вот так:

    <?
    class VKClass {
    	protected $email = "TELEPHONE";
    	protected $pass = "PASSWORD";
    	protected $auth_url = "https://m.vk.com";
    	protected $cookie = "cookie.txt";
    	protected $client_id = "XXXXXXX";
    	protected $redir_url = "http://goto.ru/token";
    
    	public function __construct() {
    		//вызываем метод для загрузки необходимых объектов
    		if(empty($_SESSION["loggedIn"]))
    			$this->logIn();
    
    		if(empty($_SESSION["access_token"]))
    			$this->getAccessToken();
    	}
    
    	public function prependCurl($options){
    		$ch = curl_init();
    		curl_setopt($ch, CURLOPT_URL, $options["url"]);
    		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $options["flocation"]);
    		curl_setopt($ch, CURLOPT_POST, $options["post"]);
    		curl_setopt($ch, CURLOPT_HEADER, $options["header"]);
    		if($options["post"])
    			curl_setopt($ch, CURLOPT_POSTFIELDS, $options["postdata"]);
    		if($options["cookie_w"])
    			curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER["DOCUMENT_ROOT"].$this->cookie);
    		if($options["cookie_r"])
    			curl_setopt($ch, CURLOPT_COOKIEFILE, $_SERVER["DOCUMENT_ROOT"].$this->cookie);
    		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    		$data = curl_exec($ch);
    		curl_close($ch);
            return $data;
    	}
    
    	public function logIn(){
    		$options = ["url" => $this->auth_url, "flocation" => 0, "post" => 0, "header" => 0, "cookie_w" => 1, "cookie_r" => 0];
    		$login_page = $this->prependCurl($options);
    		unset($options);
                    //функция str_get_html используется из бибилиотеки Simple HTML DOM Parser
    		$html = str_get_html($login_page);
    		$login_url = @$html->find("form",0)->action;
    
    		$options = ["url" => $login_url, "flocation" => 1, "post" => 1, "header" => 0, "postdata" => ["email" => $this->email, "pass" => $this->pass], "cookie_w" => 1, "cookie_r" => 1];
    		$this->prependCurl($options);
    
    		$_SESSION["loggedIn"] = $this->loggedIn= true;
    	}
    
    	public function getLocations($url){
    		$options = ["url" => $url, "flocation" => 1, "post" => 0, "header" => 1, "cookie_w" => 1, "cookie_r" => 1];
    		$data = $this->prependCurl($options);
    		return $data;
    	}
    
    	public function getAccessToken(){
    		//по ссылке возвращается access_token. собираем все заголовки запросов
    		$url = "https://oauth.vk.com/authorize?client_id=".$this->client_id."&redirect_uri=".$this->redir_url."?display=page&response_type=token";
    		$headers = $this->getLocations($url);
    		//разбиваем на кол-во запросов
    		$hdrs = explode("\r\n\r\n", $headers);
    		//т.к. у нас 2 редиректа (с oauth.vk.com на login.vk.com и с login.vk.com на домен), то нам нужен второй запрос ($hdrs[1]), где соджержится access_token
    		preg_match("/Location: (.*)/m", $hdrs[1], $matches);
    		//вырезаем наш access_token из ссылки что нам прислал вк сервер
    		@preg_match("/#access_token=(.*?)&/", $matches[1], $token);
    		//объявляем access_token в сессии и в классе
    		@$_SESSION["access_token"] = $this->access_token = $token[1];
    	}
    }

    Да, забыл что это на PHP версии.
    В JS я получал его обычным windlow.location.hash, проблема была получить его именно в PHP т.к. хэш (#) в пхп не передается.
    p.s. через некоторое время ВК стал отдавать ошибку Security Error, пришлось создать новое приложение и с ним всё работает без проблем.
    Ответ написан
    Комментировать