@ld0687

Как получить token standalone приложения с сайта?

Доброго дня.
Существуют ли решения, с помощью которых можно получить token пользователя из standalone-авторизации на сайте?

Согласно документации, нужные права доступа будут получены только в том случае, если redirect_uri указан как blank.html .

В частности, нужен доступ к методу photos.delete

У себя на сайте авторизацию провожу в новом окне. Попытка поймать location.href из родительского окна конечно же вызывает ошибку
Blocked a frame with origin "mysqte" from accessing a cross-origin frame


Уверен что есть решение, встречал сайты использующие данный метод.
Надеюсь, кто то уже задавался данной задачей и подскажет реализацию.
  • Вопрос задан
  • 91 просмотр
Пригласить эксперта
Ответы на вопрос 1
SilenceOfWinter
@SilenceOfWinter
та еще зажигалка...
ты можешь создать токен не ограниченный по времени т.ч. если приложение привязано к конкретному аккаунту, то просто генеришь его в браузере и вбиваешь полученный токен на сайте

OAuth2Vk.php
use VK\OAuth\VKOAuth;
use VK\OAuth\VKOAuthResponseType;
use VK\OAuth\VKOAuthDisplay;
use VK\OAuth\Scopes\VKOAuthUserScope;
use VK\Client\VKApiClient;

class OAuth2Vk
{
    protected $configPath;
    
    protected $config;
    
    public function __construct($configPath)
    {
        $this->configPath = $configPath;
        $this->config = include($configPath);
        if (empty($this->config['state'])) {
            $this->config['state'] = str_shuffle('abcdefghijklmnopqrstuvwxyz1234567890');
        }
    }
    
    public function setAccessToken(array $data)
    {
        if ($data['state'] != $this->config['state']) {
            throw new InvalidArgumentException('Invalid request state');
        }
        $this->config['access_token'] = $data['access_token'];
        $this->config['expires_in'] = time() + $data['expires_in'];
        $this->config['user_id'] = $data['user_id'];
        $this->config['state'] = null;
    }
    
    public function getAuthorizeUrl($revoke_auth = false)
    {
        return (new VKOAuth)->getAuthorizeUrl(
            VKOAuthResponseType::TOKEN, //  VKOAuthResponseType::CODE
            $this->config['client_id'],
            $this->config['redirect_uri'],
            VKOAuthDisplay::PAGE, // VKOAuthDisplay::POPUP
            [VKOAuthUserScope::OFFLINE, VKOAuthUserScope::WALL, VKOAuthUserScope::GROUPS],
            $this->config['state'],
            null,
            true
        );
    }
    
    public function hasAccessTokenExpired()
    {
        // $expires_in = $this->config['expires_in'] ?: 0;
        return empty($this->config['expires_in']) || $this->config['expires_in'] <= time();
    }
    
    public function addPost(array $post)
    {
        if ($this->hasAccessTokenExpired()) {
            throw new InvalidArgumentException('Access token expired');
        }
        
        return (new VKApiClient)->wall()->post(
            $this->config['access_token'], 
            [
                'owner_id'           => $this->config['user_id'],
                'message'            => $post['message'],
                'attachments'        => [$post['link']],
                'guid'               => time(),
                'close_comments'     => 0,
                'mute_notifications' => 0,
            ]
        );
    }
    
    public function __destruct()
    {
        file_put_contents(
            $this->configPath, 
            '<?php return ' . var_export($this->config, true) . ';'
        );
    }
}

oauth2/vk.php
<?php
return [
    'client_id'     => 7...9,
    'client_secret' => '...',
    'group_id'      => 1...9,
    'redirect_uri'  => '.../oauth2/redirect/vk/',
    'base_uri'      => '.../oauth2/base/vk/',
    'state'         => '123',
];

отправка
$oauth = new OAuth2Vk(__DIR__ . '/oauth2/vk.php');
if (filter_input(INPUT_GET, 'access_token')) {
    $oauth->setAccessToken($_GET);
    header('Location: vk.php');
} elseif ($oauth->hasAccessTokenExpired()) {
    header('Location: ' . $oauth->getAuthorizeUrl());
} else {
    try {
        $response = $oauth->addPost([
            'message' => 'Проверка связи! https://site.ru the end!',
            'link' => 'https://site.ru/test-link/',
        ]);
        var_dump($response);
    } catch (Exception $e) {
        var_dump($e);
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы