vk/Auth.php

332 lines
10 KiB
PHP
Raw Normal View History

2020-06-06 15:27:31 +07:00
<?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));
}
}