Без жира Используйте Google OAuth + Google API

Я уже давно пытаюсь сделать следующее и сильно борюсь...

На веб-сайте я сначала хочу аутентифицировать пользователя с его учетной записью Google с помощью OAuth. Поэтому я использую эту библиотеку. Чтобы заставить его работать, я использовал $f3->set('AUTOLOAD','vendor/ikkez/f3-opauth/lib/opauth/'); для загрузки файлов PHP, а затем использовал следующий код для создания маршрутов и обеспечения возможности аутентификации:

$f3 = \Base::instance();
// load opauth config (allow token resolve)
$f3->config('vendor/ikkez/f3-opauth/lib/opauth/opauth.ini', TRUE);

// init with config
$opauth = OpauthBridge::instance($f3->opauth);

// define login handler
$opauth->onSuccess(function($data){
    header('Content-Type: text');

    //$data['credentials']['token'];
});

// define error handler
$opauth->onAbort(function($data){
    header('Content-Type: text');
    echo 'Auth request was canceled.'."\n";
    print_r($data);
});

Пока все хорошо, все работает нормально, как только разрешение предоставлено Google, я получаю правильный обратный вызов, включая токен входа.

Теперь следующий шаг заключается в том, что после того, как пользователь дал разрешение на это (путем аутентификации), я хочу проверить, подписался ли пользователь на определенный канал на Youtube (и затем сохранить эту информацию в моей БД, распечатав ее на первом шаге). хоть хватит).

Теперь я делал домашнюю работу в течение нескольких часов, пытаясь понять, как это работает...

Что я (в общем нашел) так это то, что следующий запрос на завивание должен дать мне желаемый результат:

curl \
  'https://youtube.googleapis.com/youtube/v3/subscriptions?part=snippet%2CcontentDetails&forChannelId=UC_x5XG1OV2P6uZZ5FSM9Ttw&mine=true&key=[YOUR_API_KEY]' \
  --header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
  --header 'Accept: application/json' \
  --compressed

Затем я попытался отправить этот запрос на завивание с помощью PHP, заменив КЛЮЧ API моим ключом API Google и YOUR_ACCESS_TOKEN токеном, который я получил от OAUTH.... Однако он выдает ошибку, говоря, что в запросе недостаточно областей аутентификации... Это кажется, потому что при проверке примера PHP из Google я должен предоставить области видимости, которые я использую - в моем случае https://www.googleapis.com/auth/youtube.readonly.

Код PHP, предоставленный Google, выглядит следующим образом:

<?php

/**
 * Sample PHP code for youtube.subscriptions.list
 * See instructions for running these code samples locally:
 * https://developers.google.com/explorer-help/guides/code_samples#php
 */

if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
  throw new Exception(sprintf('Please run "composer require google/apiclient:~2.0" in "%s"', __DIR__));
}
require_once __DIR__ . '/vendor/autoload.php';

$client = new Google_Client();
$client->setApplicationName('API code samples');
$client->setScopes([
    'https://www.googleapis.com/auth/youtube.readonly',
]);

// TODO: For this request to work, you must replace
//       "YOUR_CLIENT_SECRET_FILE.json" with a pointer to your
//       client_secret.json file. For more information, see
//       https://cloud.google.com/iam/docs/creating-managing-service-account-keys
$client->setAuthConfig('YOUR_CLIENT_SECRET_FILE.json');
$client->setAccessType('offline');

// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open this link in your browser:\n%s\n", $authUrl);
print('Enter verification code: ');
$authCode = trim(fgets(STDIN));

// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);

// Define service object for making API requests.
$service = new Google_Service_YouTube($client);

$queryParams = [
    'forChannelId' => 'UC_x5XG1OV2P6uZZ5FSM9Ttw',
    'mine' => true
];

$response = $service->subscriptions->listSubscriptions('snippet,contentDetails', $queryParams);
print_r($response);

Это позволило мне столкнуться с новой проблемой... Пытаясь использовать этот код, я получаю сообщение об ошибке, что Google_Client не известен как класс... Затем я установил Google Client с Composer и попытался использовать vendor/autoload.php в чтобы использовать класс.... Однако при включении autoload.php я получаю сообщение об ошибке Fatal error: Cannot declare class Prefab, because the name is already in use... Похоже, это так, потому что f3-opauth уже объявляет этот класс Prefab, а затем google apiclient пытается объявить его снова.. Однако без автозагрузки у меня не получилось включить google apiclient...

Видите ли, я действительно много пробовал, и сегодня я работал над этим около 5-6 часов, заставив работать только один запрос API, и я не знаю, что еще попробовать...

Буду признателен за любой намек на то, как заставить его работать - если есть какой-либо намек на то, чтобы сделать это совершенно по-другому, я бы также хотел изменить его, поскольку сам проект только начался.

Подводя итог, я пытаюсь сделать следующее: -> Пользователь может войти на веб-сайт со своей учетной записью Youtube/Google -> При аутентификации проверяется, является ли пользователь подписчиком определенного канала. Следующим шагом будет также проверка, является ли он участником этого конкретного канала. Обе информации должны быть сохранены в базе данных

-› после этого пользователь всегда может снова войти в свою учетную запись в Google и в базе данных можно найти информацию, является ли пользователь подписчиком и/или участником этого канала..

Заранее спасибо!


person nameless    schedule 03.01.2021    source источник


Ответы (1)


Я не уверен, поможет ли это в вашем конкретном случае использования, но в прошлом я работал с Google API с Fat-Free. Я не мог заставить его работать сразу, поэтому я установил и заработал с помощью Google Client/API/SDK. Как только у меня это заработало, я начал работать в обратном направлении, чтобы посмотреть, смогу ли я заставить это работать с Fat-Free. Одна из вещей, с которой я столкнулся, это отсутствие полей в запросе Oauth. access_type зацепил меня так же, как и approval_prompt. Я знаю, что вы сказали, что уже получили свой токен доступа, поэтому он может не применяться, но может использоваться для будущих запросов. Вот пример кода, который я разработал для создания URL-адреса oauth для входа в Google, а затем для обработки запроса и вызова части userinfo.

<?php 

class App_Auth {
    public static function generateOauthUrl() {
        $fw = Base::instance();
        $Oauth = new \Web\OAuth2();
        $Oauth->set('client_id', $fw->get('google.client_id'));
        $Oauth->set('scope', 'profile email');
        $Oauth->set('response_type', 'code');
        $Oauth->set('access_type', 'online');
        $Oauth->set('approval_prompt', 'auto');
        $Oauth->set('redirect_uri', $fw->SCHEME.'://' . $_SERVER['HTTP_HOST'] . $fw->BASE.'/oauthRedirect');
        return $Oauth->uri('https://accounts.google.com/o/oauth2/auth', true);
    }

    public static function processAuthCodeAndGetToken($auth_code) {
        $fw = Base::instance();
        $Oauth = new \Web\OAuth2();
        $Oauth->set('client_id', $fw->get('google.client_id'));
        $Oauth->set('client_secret', $fw->get('google.client_secret'));
        $Oauth->set('scope', 'profile email');
        $Oauth->set('access_type', 'online');
        $Oauth->set('grant_type', 'authorization_code');
        $Oauth->set('code', $auth_code);
        $Oauth->set('approval_prompt', 'auto');
        $Oauth->set('redirect_uri', $fw->SCHEME.'://' . $_SERVER['HTTP_HOST'] . $fw->BASE.'/oauthRedirect');
        return $Oauth->request('https://oauth2.googleapis.com/token', 'POST');
    }

    public static function getOauthUserInfo($access_token) {
        $Oauth_User_Info = new \Web\OAuth2();
        return $Oauth_User_Info->request('https://www.googleapis.com/oauth2/v2/userinfo', 'GET', $access_token);
    }

Еще одна ошибка, которая укусила меня за зад, заключалась в том, что мы получали наш токен доступа от Google, а затем сохраняли его в базе данных для последующих запросов. Мы получили бы ту ошибку областей, о которой вы упомянули request had insufficient authentication scopes. В конце концов мы выяснили, что access_token длиннее, чем наше поле базы данных (VARCHAR(32), если я правильно помню), поэтому нам нужно было сделать наше поле базы данных длиннее, чтобы оно могло хранить все это.

Надеемся, что один из них спровоцирует что-то, что поможет вам разобраться в вашей проблеме.

person n0nag0n    schedule 04.01.2021