vk/Auth.php

335 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Created by PhpStorm.
* User: zerox
* Date: 25.08.18
* Time: 19:27
*/
namespace VK;
require_once('config_library.php');
/**
* Class Auth
* @package VK
*/
class Auth
{
/**
* @var null
*/
private $login = null;
/**
* @var null
*/
private $pass = null;
/**
* @var mixed|null
*/
private $cookie = null;
/**
* @var mixed|string
*/
private $useragent = DEFAULT_USERAGENT;
/**
* @var mixed|string
*/
private $id_app = DEFAULT_ID_APP;
/**
* @var string
*/
private $access_token = '';
/**
* @var string
*/
private $scope = '';
/**
* @var string
*/
private $method = '';
/**
* @var string
*/
private $default_scope = DEFAULT_SCOPE;
/**
* @var int
*/
private $is_auth = 0;
/**
* @var int
*/
private $auth_method = 0; //0 - mobile, 1 - app
/**
* @var null
*/
private $captcha_sid = null;
/**
* Auth constructor.
* @param $login
* @param null $pass
* @param null $other
* @param bool $mobile
* @throws VkApiException
*/
public function __construct($login, $pass = null, $other = null, $mobile = true)
{
if (!isset($login))
throw new VkApiException("Укажите логин и пароль либо куки");
if (is_array($other)) {
if (isset($other['useragent']))
$this->useragent = $other['useragent'];
if (isset($other['id_app']))
$this->id_app = $other['id_app'];
}
if (isset($pass)) {
$this->login = $login;
$this->pass = $pass;
$this->method = 'pass';
if (!$mobile)
$this->auth_method = 1;
} else {
$this->method = 'cookie';
$this->cookie = json_decode($login, true);
$this->auth_method = 1;
}
}
/**
* @throws VkApiException
*/
public function auth()
{
if ($this->auth_method == 0)
throw new VkApiException("Только для авторизации через приложение");
$this->loginInVK();
}
/**
* @throws VkApiException
*/
private function loginInVK()
{
$query_main_page = $this->getCURL('https://vk.com/');
preg_match('/name=\"ip_h\" value=\"(.*?)\"/s', $query_main_page['body'], $ip_h);
preg_match('/name=\"lg_h\" value=\"(.*?)\"/s', $query_main_page['body'], $lg_h);
$values_auth = [
'act' => 'login',
'role' => 'al_frame',
'_origin' => 'https://vk.com',
'utf8' => '1',
'email' => $this->login,
'pass' => $this->pass,
'lg_h' => $lg_h[1],
'ig_h' => $ip_h[1]
];
$get_url_redirect_auch = $this->getCURL('https://login.vk.com/?act=login', $values_auth);
if (!isset($get_url_redirect_auch['header']['location']))
throw new VkApiException("Ошибка, ссылка редиректа не получена");
$auth_page = $this->getCURL($get_url_redirect_auch['header']['location'][0]);
if (!isset($auth_page['header']['set-cookie']))
throw new VkApiException("Ошибка, куки пользователя не получены");
$this->is_auth = 1;
}
/**
* @param $url
* @param null $post_values
* @param bool $cookie
* @return array
*/
private function getCURL($url, $post_values = null, $cookie = true)
{
if ($curl = curl_init()) {
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_USERAGENT, $this->useragent);
if (isset($post_values)) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_values);
}
//
// curl_setopt($curl, CURLOPT_HTTPHEADER, [
// "Content-Type: application/x-www-form-urlencoded",
// "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
// "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36"
// ]);
if ($cookie and isset($this->cookie)) {
$send_cookie = [];
foreach ($this->cookie as $cookie_name => $cookie_val) {
$send_cookie[] = "$cookie_name=$cookie_val";
}
curl_setopt($curl, CURLOPT_COOKIE, join('; ', $send_cookie));
}
curl_setopt(
$curl,
CURLOPT_HEADERFUNCTION,
function ($curl, $header) use (&$headers) {
$len = strlen($header);
$header = explode(':', $header, 2);
if (count($header) < 2) // ignore invalid headers
return $len;
$name = strtolower(trim($header[0]));
if (isset($headers) and !array_key_exists($name, $headers))
$headers[$name] = [trim($header[1])];
else
$headers[$name][] = trim($header[1]);
return $len;
}
);
$out = curl_exec($curl);
curl_close($curl);
if (isset($headers['set-cookie']))
$this->parseCookie($headers['set-cookie']);
return ['header' => $headers, 'body' => $out];
}
}
/**
* @param $new_cookie
*/
private function parseCookie($new_cookie)
{
foreach ($new_cookie as $cookie) {
preg_match("!(.*?)=(.*?);(.*)!s", $cookie, $preger);
if ($preger[2] == 'DELETED')
unset($this->cookie[$preger[1]]);
else
$this->cookie[$preger[1]] = $preger[2] . ';' . $preger[3];
}
}
/**
* @return false|string
*/
public function dumpCookie()
{
return json_encode($this->cookie);
}
/**
* @return bool
*/
public function isAuth()
{
$header = $this->getCURL("https://vk.com/feed")['header'];
if (isset($header['location'][0]) and strpos($header['location'][0], 'login.vk.com'))
return False;
return True;
}
/**
* @param null $captcha_key
* @param null $captcha_sid
* @return string
* @throws VkApiException
*/
public function getAccessToken($captcha_key = null, $captcha_sid = null)
{
if ($this->access_token != '')
return $this->access_token;
if ($this->auth_method) {
if ($this->is_auth == 0)
$this->loginInVK();
if ($this->access_token == '')
$this->access_token = $this->generateAccessToken();
} else {
if (isset($this->captcha_sid))
$captcha_sid = $this->captcha_sid;
$this->access_token = $this->generateAccessTokenMobile($captcha_key, $captcha_sid);
}
return $this->access_token;
}
/**
* @param null $scope
* @param bool $resend
* @return mixed
* @throws VkApiException
*/
private function generateAccessToken($scope = null, $resend = false)
{
$this->scope = [];
if (!isset($scope)) {
$scope = $this->default_scope;
}
foreach (preg_split("!,!", $scope) as $one_scope)
$this->scope[] = $one_scope;
$scope = "&scope=$scope";
if ($resend)
$scope .= "&revoke=1";
$token_url = 'https://oauth.vk.com/authorize?client_id=' . $this->id_app .
$scope .
'&response_type=token';
$get_url_token = $this->getCURL($token_url);
if (isset($get_url_token['header']['location'][0]))
$url_token = $get_url_token['header']['location'][0];
else {
preg_match('!location.href = "(.*)"\+addr!s', $get_url_token['body'], $url_token);
if (!isset($url_token[1])) {
throw new VkApiException("Не получилось получить токен на этапе получения ссылки подтверждения");
}
$url_token = $url_token[1];
}
$access_token_location = $this->getCURL($url_token)['header']['location'][0];
if (preg_match("!access_token=(.*?)&!s", $access_token_location, $access_token) != 1)
throw new VkApiException("Не удалось найти access_token в строке ридеректа, ошибка:" . $this->getCURL($access_token_location, null, false)['body']);
return $access_token[1];
}
/**
* @param $captcha_key
* @param $captcha_sid
* @return mixed
* @throws VkApiException
*/
private function generateAccessTokenMobile($captcha_key, $captcha_sid)
{
if (!isset($this->pass))
throw new VkApiException("Метод работает только с логином и паролем");
$captcha = '';
$this->scope = [];
$scope = $this->default_scope;
foreach (preg_split("!,!", $scope) as $one_scope)
$this->scope[] = $one_scope;
$scope = "&scope=$scope";
if (isset($captcha_sid) and isset($captcha_key))
$captcha = "&captcha_sid=$captcha_sid&captcha_key=$captcha_key";
$token_url = 'https://oauth.vk.com/token?grant_type=password&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH' .
'&username=' . $this->login .
'&password=' . $this->pass .
$scope .
$captcha;
$response_auth = $this->getCURL($token_url, null, false)['body'];
$response_auth = json_decode($response_auth, true);
if (isset($response_auth['access_token']))
return $response_auth['access_token'];
else
throw new VkApiException(json_encode($response_auth));
}
}