laravel — Аутентификация API Google Analytics

Я пытаюсь создать веб-приложение с простой панелью инструментов с данными аналитики для учетных записей, которые вошли в систему с помощью Google. Я использую Laravel с пакетом Socialite, и в настоящее время я могу регистрировать пользователей с помощью Google. У меня есть клиентский ключ разработчика и клиентский секрет. Я устанавливаю области для Analytics только для чтения и автономного доступа, а также храню имя клиента, адрес электронной почты, идентификатор Google, токен доступа и токен обновления в своей базе данных. Я могу войти в систему без проблем.

Что я хочу сделать, так это просто получить доступ к профилям, которые в настоящее время есть в учетной записи Google Analytics. Я следил за примерами документации Analytics API, но не смог заставить его работать. Поскольку я храню токен доступа и токен обновления, я думаю, что смогу аутентифицировать текущего пользователя и получить его данные Analytics, но я не смог найти простых методов из библиотек Client и Analytics. Мне нужно будет получить доступ к их данным Analytics в автономном режиме, и именно поэтому я думаю, что должен иметь возможность авторизовать свои запросы с помощью токена доступа и токена обновления, но я не получаю никаких конкретных данных Analytics из процесса входа пользователя. Я совершенно потерялся, как мне авторизовать свои запросы к Anayltics API? Я использую AdWords API более 8 месяцев, и в документации AdWords API все предельно ясно, но я не смог заставить ничего работать с Analytics API.

Это мои методы входа в систему:

public function redirectToProvider()
{
    $parameters = ['access_type' => 'offline'];
    return Socialite::driver('google')
        ->scopes(['https://www.googleapis.com/auth/analytics.readonly'])
        ->with($parameters)
        ->redirect();
}

/**
 * Obtain the user information from Google.
 *
 * @return Response
 */
public function handleProviderCallback()
{
    $outsiderLogin = Socialite::driver('google')->stateless()->user();


    $user = User::where('googleID', $outsiderLogin->id)->first();

    // Register the user if there is no user with that id.
    if (!$user) {
        $user = new User;
        $user->name         = $outsiderLogin->name;
        $user->googleID     = $outsiderLogin->id;
        $user->email        = $outsiderLogin->email;
        $user->token        = $outsiderLogin->token;
        $user->refreshToken = $outsiderLogin->refreshToken;
        $user->save();
    }
    // Log the user in.
    Auth::login($user);

    return redirect('/home');
}

Большое Вам спасибо.


person Burak Karakan    schedule 08.07.2016    source источник


Ответы (3)


Я нашел решение на данный момент. Сначала я решил, что мне нужен код, который возвращает URL-адрес аутентификации из Google, и когда я проверял пакет Socialite, я нашел защищенный метод getCode() в \vendor\laravel\socialite\src\Two\AbstractProvider.php, который возвращает код из URL-адреса. Я отредактировал исходный файл пакета и изменил тип метода с protected на public, что позволило использовать этот метод вне класса, что позволило мне получить доступ к коду из URL-адреса, а затем сохранить его в БД для дальнейшего использования. требования аутентификации. Но были проблемы с этой настройкой, во-первых, я должен найти способ сохранить этот пакет без каких-либо обновлений, так как любое обновление откатит изменения, которые я внес в исходный файл. Вторая проблема, с которой я столкнулся, заключалась в том, как я храню токены. По умолчанию Google Client API возвращает массив, содержащий поля access_token, refresh_token, expires_in, id и created, и с помощью этих полей он аутентифицирует запросы к серверу Analytics. В моем сценарии не было стандартного массива, возвращаемого из базового процесса входа в систему Socialite. Там было access_token, refresh_token и expires переменных, и я сохранил их все в своей базе данных. Это вызвало проблему с библиотекой Google, она запросила структурированный массив, а у меня даже не было переменных expires_in и created, поэтому я установил поддельный массив, который говорит Google обновлять токен при каждом запросе, и это было нехорошо. практика же.

В итоге я так и не смог понять как пользоваться любым пакетом онлайн и написал свою простую аутентификацию, и не знаю есть ли в ней уязвимости, но у меня работает, может сработает и у тех кому нужно.

Вот мои маршруты:

Route::get('auth/google', [
            'as' => 'googleLogin',   
            'uses' => 'Auth\AuthController@redirectToProvider'
]);
Route::get('auth/google/callback', [
            'as' => 'googleLoginCallback',   
            'uses' => 'Auth\AuthController@handleProviderCallback'
]);

А это методы AuthController:

/**
 * Redirect the user to the Google authentication 
 */
public function redirectToProvider()
{
    // Create the client object and set the authorization configuration from JSON file.
    $client = new Google_Client();
    $client->setAuthConfig('/home/vagrant/Analytics/client_secret.json');
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/auth/google/callback');
    $client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
    $client->addScope("email");
    $client->addScope("profile");
    $client->setAccessType("offline");

    $auth_url = $client->createAuthUrl();
    return redirect($auth_url);

}

/**
 * Obtain the user information from Google.
 *
 * @return redirect to the app.
 */
public function handleProviderCallback()
{
    // Handle authorization flow from the server.
    if (! isset($_GET['code'])) {
        return redirect('auth/google');
    } else {

        // Authenticate the client, and get required informations.
        $client = new Google_Client();
        $client->setAuthConfig('/home/vagrant/Analytics/client_secret.json');
        $client->authenticate($_GET['code']);

        // Store the tokens in the session.
        Session::put('token', $client->getAccessToken());

        $service = new Google_Service_Oauth2($client);
        $userInfo = $service->userinfo->get();

        $user = User::where('googleID', $userInfo->id)->first();

        // If no match, register the user.
        if(!$user) {
            $user = new User;
            $user->name = $userInfo->name;
            $user->googleID = $userInfo->id;
            $user->email = $userInfo->email;
            $user->refreshToken = $client->getRefreshToken();
            $user->code = $_GET['code'];
            $user->save();
        }

        Auth::login($user);
        return redirect('/home');
    }

}

Я поместил файл client_secret.json, загруженный из Google API Console, в указанную папку, у вас это может быть иначе. Я также изменил файл миграции, чтобы он соответствовал требуемым сегментам. После этих шагов я могу относиться к этому пользователю как к простому пользователю, который зарегистрировался с помощью базовой аутентификации Laravel.

Теперь я могу запросить, скажем, учетные записи в учетной записи пользователя Google Analytics следующим образом:

/**
 * @var $client to be authorized by Google.
 */
private $client;

/**
 * @var $analytics Analytics object to be used.
 */
private $analytics;

public function __construct()
{
    $this->client = $this->AuthenticateCurrentClient();
    $this->analytics = new Google_Service_Analytics($this->client);
}

private function AuthenticateCurrentClient(){
    $user = Auth::user();
    $token = Session::get('token');

    // Authenticate the client.
    $client = new Google_Client();
    $client->setAccessToken($token);
    $client->authenticate($user->code);
    return $client;
}

public function GetAccounts(){

    try {
        $accountsObject = $this->analytics->management_accounts->listManagementAccounts();
        $accounts = $accountsObject->getItems();

        return $accounts;

    } catch (apiServiceException $e) {
        print 'There was an Analytics API service error '
            . $e->getCode() . ':' . $e->getMessage();

    } catch (apiException $e) {
        print 'There was a general API error '
            . $e->getCode() . ':' . $e->getMessage();
    }

}

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

person Burak Karakan    schedule 09.07.2016

Вы не на самом деле найдете то, что ищете, с пакетом Socialite, поставляемым с Laravel (который больше используется для входа в систему, и это все).

Однако вы можете найти множество пакетов Google Analytics (наряду со многими другими пакетами Laravel), которые помогут вам выполнять вызовы API:

http://packalyst.com/s/google%20analytics

В частности, этот пакет: https://github.com/spatie/laravel-analytics

Это или запустить свои собственные сценарии Guzzle и cURL. Я использую Guzzle, когда мне нужно что-то быстрое, без создания полноценного API.

Однако здесь есть интересный пост об использовании Socialite для доступа к данным GA. Но вы весьма ограничены. Если вы создаете панели мониторинга, управляемые пользователями, я бы выбрал отдельный пакет.

https://laracasts.com/discuss/channels/tips/how-i-made-google-analytics-work-with-socialite

person Mike Barwick    schedule 09.07.2016
comment
Прежде всего, большое спасибо. Я видел большинство этих пакетов, но для этих пакетов, похоже, требуется идентификатор просмотра Google Analytics, который выглядит как ga-123456, и я не думаю, что это хороший пользовательский интерфейс. Как пользователь, я хотел бы, чтобы эта веб-страница получала все данные без моих дополнительных усилий после успешной аутентификации. Тут все усложняется, мне нужно получить данные из GA, а нет view ID или ничего не происходит с процессом авторизации, тут я и застрял. У меня есть токены доступа, но ни один из этих пакетов не работает с этими токенами доступа? - person Burak Karakan; 09.07.2016
comment
Светская львица - это НЕ ваш ответ. Так что надо смотреть разные варианты. Я использую этот пакет для всех своих сервисов Google API. Но поищите Packalyst и найдите тот, который вам наиболее удобен. github.com/pulkitjalan/google-apiclient - person Mike Barwick; 09.07.2016
comment
Большое Вам спасибо. На данный момент я нашел свой путь с Socialite, и, поскольку у меня есть крайний срок для проекта, я думаю, что буду использовать его в том виде, в каком он есть сейчас, до MVP. Я думаю, что я перейду на пакет, который вы используете, он кажется довольно простым в использовании. Спасибо, вы помогли мне разобраться. - person Burak Karakan; 09.07.2016

Я также пытаюсь сделать то же самое. На данный момент у меня есть аутентификация пользователя с пакетом oAuth 2.0 и Socialite. Мне нужен список сайтов, которые нужно получить из GA. И я полностью застрял там. Было бы действительно здорово, если бы вы могли указать мне, как мне двигаться дальше.

person NewBee    schedule 14.07.2016
comment
Socialite не подходит для такого рода процессов аутентификации или обмена данными через API. Вам нужно обновить исходный код пакета Socialite, что не имеет смысла, так как вам нужно будет повторять свои изменения при каждом обновлении. Socialite предназначен только для простых операций входа в систему, где вам просто нужна информация о пользователе. Вы проверили мой ответ здесь? Я предоставил код для получения учетных записей. Я не уверен, есть ли прямой способ получить сайты, но вы можете получить учетные записи GA, а затем свойства, которые поставляются с URL-адресами для каждого из свойств. - person Burak Karakan; 14.07.2016
comment
Какой код? Весь код находится здесь, а остальные части кода связаны с бизнесом. Вы можете войти в систему и получить отчет об учетных записях с помощью этих методов в сообщении. Я могу, может быть, создать суть или что-то в этом роде, когда у меня будет время, если хотите. - person Burak Karakan; 14.07.2016
comment
Да, пожалуйста. Я также хотел узнать о guzzle-запросах - person NewBee; 15.07.2016
comment
если вы можете опубликовать Google_Client(), Google_Service_Analytics и Google_Service_Oauth2(), это было бы очень полезно - person NewBee; 16.07.2016
comment
Это из клиентской библиотеки Google, я ничего не писал в эти классы или методы. Я проверил свои файлы, и в приведенном выше коде действительно нет ничего дополнительного. Что вам конкретно нужно, чем я могу помочь? - person Burak Karakan; 16.07.2016
comment
Я пробовал их, но они мне не подходят. Я использую google/apiclient 1.1, а вы используете? А также, используете ли вы учетные данные серверного приложения или веб-приложения из API консоли Google? - person NewBee; 18.07.2016
comment
привет, извините, что беспокою вас, но если вы можете сказать мне, какой файл (где) вы запрашиваете, то есть второй фрагмент кода? Пожалуйста помогите! - person NewBee; 18.07.2016
comment
Вот файл контроллера, который я создал. Я получаю пользователя с oAuth, затем с этой информацией я запрашиваю клиентскую библиотеку Google API с заданными кодами, я думаю, это может дать вам представление. ссылка Кроме того, я работаю над веб-приложением, поэтому у меня есть учетные данные для веб-приложение. Композитор клиента Google API требует google/apiclient: ^ 2.0 для меня, вы должны проверить их GitHub. - person Burak Karakan; 18.07.2016
comment
Я попробовал composer require is google/apiclient: ^2.0, но он конфликтует с пакетом socialite (может быть, мне вообще стоит отказаться от socialite?) плюс спасибо за контроллер, с вашей стороны он выглядит идеально, но не знаю, почему я застрял . Если вы можете поделиться своим адресом электронной почты, чтобы я мог отправить вам свои файлы, чтобы вы имели точное представление, пожалуйста? - person NewBee; 19.07.2016
comment
Вы должны определенно отказаться от Socialite в первую очередь. Но, вероятно, коллизия была не из-за этого, я использовал их оба одновременно в приложении. Вы должны проверить GitHub клиента Google API и следовать приведенным там инструкциям. Я не могу предоставить свою электронную почту, и у меня нет времени на отладку. Это навык, которым все мы должны овладеть, поэтому вам нужно найти свой путь самостоятельно с помощью своего кода. Если вы не можете ее решить, просто задайте ее как вопрос, а не спрашивайте меня, есть тысячи людей лучше меня. - person Burak Karakan; 19.07.2016
comment
Привет! Я это понимаю и уважаю. Я пытался, как вы упомянули. но когда я пытаюсь получить учетные записи в другом контроллере, он выдает ошибку: Google_Auth_Exception в OAuth2.php: ошибка при получении токена доступа OAuth2, сообщение: «invalid_request: не удалось определить идентификатор клиента из запроса». может вы сталкивались? - person NewBee; 20.07.2016
comment
Похоже, вы неправильно установили свой идентификатор клиента и секреты клиента. На странице учетных данных есть файл JSON, который вы загружаете из Google API Console и который называется секретами клиента. Вы должны загрузить его в свой каталог, а затем передать его API с помощью $client->setAuthConfig('/home/vagrant/Analytics/client_secret.json');, так как путь будет изменен для вас независимо от вашего пути к файлу client_secrets. Это что-то вроде client_secret12839739827594, и я переименовал его, так что будьте осторожны с этим. Если не можете решить, задайте вопрос. - person Burak Karakan; 20.07.2016
comment
эй ммм как вы называете второй контроллер? Какой маршрут? Нужно ли с ним что-то уплотнять? - person NewBee; 21.07.2016
comment
Что вы имеете в виду под вторым контроллером? Маршрут Auth Controller прописан там, и вам также нужен еще один маршрут для контроллера GetAccounts(), поэтому мы используем маршруты. Вам нужно вызвать функцию с маршрутом. Compact — это просто возврат чего-то в представление или куда-то еще, он не имеет ничего общего с вызовом функции. Если вы хотите получить конкретную информацию об учетной записи, вам нужно опубликовать некоторый идентификатор с маршрутом в качестве почтового запроса, и ваш контроллер обработает его. Я считаю, что вам определенно следует прочитать документы Laravel. - person Burak Karakan; 21.07.2016