Search code examples
phpgoogle-apigoogle-oauthgoogle-analytics-apigoogle-api-php-client

Getting started wtih Google Management API (PHP - Web Server) - Error 500


Following the Google documentation for Web Server PHP flow located here, I was able to successfully prompt user login with oauth2callback.php. However, returning to the original site after authentication throws an internal server error 500 and does not display the GA results from profile obtained as intended.

How do I know what caused the issue?

Note: Code is taken directly from Google Documentation for Web Server PHP flow with minor adjustments to my own project's parameters.

testoauth.php

<?php
// Load the Google API PHP Client Library.
require_once '../application/third_party/vendor/autoload.php';

// Start a session to persist credentials.
session_start();

// Create the client object and set the authorization configuration
// from the client_secretes.json you downloaded from the developer console.
$client = new Google_Client();
$client->setAuthConfig('../application/views/dashboard/client_secret_file.json');
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);

// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
// Set the access token on the client.
$client->setAccessToken($_SESSION['access_token']);

// Create an authorized analytics service object.
$analytics = new Google_Service_Analytics($client);

// Get the first view (profile) id for the authorized user.
$profile = getFirstProfileId($analytics);

// Get the results from the Core Reporting API and print the results.
$results = getResults($analytics, $profile);
printResults($results);
}
else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '../application/views/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

function getFirstProfileId($analytics) {
// Get the user's first view (profile) ID.
// Get the list of accounts for the authorized user.
$accounts = $analytics->management_accounts->listManagementAccounts();

if (count($accounts->getItems()) > 0) {
    $items = $accounts->getItems();
    $firstAccountId = $items[0]->getId();

    // Get the list of properties for the authorized user.
    $properties = $analytics->management_webproperties
        ->listManagementWebproperties($firstAccountId);

    if (count($properties->getItems()) > 0) {
    $items = $properties->getItems();
    $firstPropertyId = $items[0]->getId();

    // Get the list of views (profiles) for the authorized user.
    $profiles = $analytics->management_profiles
        ->listManagementProfiles($firstAccountId, $firstPropertyId);

    if (count($profiles->getItems()) > 0) {
        $items = $profiles->getItems();

        // Return the first view (profile) ID.
        return $items[0]->getId();

    } else {
        throw new Exception('No views (profiles) found for this user.');
    }
    } else {
    throw new Exception('No properties found for this user.');
    }
} else {
    throw new Exception('No accounts found for this user.');
}
}

function getResults($analytics, $profileId) {
// Calls the Core Reporting API and queries for the number of sessions
// for the last seven days.
return $analytics->data_ga->get(
    'ga:' . $profileId,
    '7daysAgo',
    'today',
    'ga:sessions');
}

function printResults($results) {
// Parses the response from the Core Reporting API and prints
// the profile name and total sessions.
if (count($results->getRows()) > 0) {

    // Get the profile name.
    $profileName = $results->getProfileInfo()->getProfileName();

    // Get the entry for the first entry in the first row.
    $rows = $results->getRows();
    $sessions = $rows[0][0];

    // Print the results.
    print "<p>First view (profile) found: $profileName</p>";
    print "<p>Total sessions: $sessions</p>";
} else {
    print "<p>No results found.</p>";
}
}
?>

oauth2callback.php

<?php
// Load the Google API PHP Client Library.
require_once '../application/third_party/vendor/autoload.php';

// Start a session to persist credentials.
session_start();

// Create the client object and set the authorization configuration
// from the client_secrets.json you downloaded from the Developers Console.
$client = new Google_Client();
$client->setAuthConfig('../application/views/dashboard/client_secret_file.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '../application/views/oauth2callback.php');
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);

// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '../application/views/testoauth.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>

Solution

  • Its hard to know what could be wrong with your code without you debugging your way though it. It is possible that that code has not been updated and the library has changed. This is the code from my sample project it was generated recently. There is a Read men on how to use the samples here

    Oauthcallback.php

    require_once __DIR__ . '/vendor/autoload.php';
    require_once __DIR__ . '/Oauth2Authentication.php';
    // Start a session to persist credentials.
    session_start();
    // Handle authorization flow from the server.
    if (! isset($_GET['code'])) {
        $client = buildClient();
        $auth_url = $client->createAuthUrl();
        header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
    } else {
        $client = buildClient();
        $client->authenticate($_GET['code']); // Exchange the authencation code for a refresh token and access token.
        // Add access token and refresh token to seession.
        $_SESSION['access_token'] = $client->getAccessToken();
        $_SESSION['refresh_token'] = $client->getRefreshToken();    
        //Redirect back to main script
        $redirect_uri = str_replace("oauth2callback.php",$_SESSION['mainScript'],$client->getRedirectUri());    
        header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }
    

    Oauth2Authentication.php

    require_once __DIR__ . '/vendor/autoload.php';
    /**
     * Gets the Google client refreshing auth if needed.
     * Documentation: https://developers.google.com/identity/protocols/OAuth2
     * Initializes a client object.
     * @return A google client object.
     */
    function getGoogleClient() {
        $client = getOauth2Client();
        // Refresh the token if it's expired.
        if ($client->isAccessTokenExpired()) {
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
            file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
        }
    return $client;
    }
    /**
     * Builds the Google client object.
     * Documentation: https://developers.google.com/identity/protocols/OAuth2
     * Scopes will need to be changed depending upon the API's being accessed.
     * Example:  array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
     * List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
     * @return A google client object.
     */
    function buildClient(){
    
        $client = new Google_Client();
        $client->setAccessType("offline");        // offline access.  Will result in a refresh token
        $client->setIncludeGrantedScopes(true);   // incremental auth
        $client->setAuthConfig(__DIR__ . '/client_secrets.json');
        $client->addScope([YOUR SCOPES HERE]);
        $client->setRedirectUri(getRedirectUri());  
        return $client;
    }
    /**
     * Builds the redirect uri.
     * Documentation: https://developers.google.com/api-client-library/python/auth/installed-app#choosingredirecturi
     * Hostname and current server path are needed to redirect to oauth2callback.php
     * @return A redirect uri.
     */
    function getRedirectUri(){
        //Building Redirect URI
        $url = $_SERVER['REQUEST_URI'];                    //returns the current URL
        if(strrpos($url, '?') > 0)
            $url = substr($url, 0, strrpos($url, '?') );  // Removing any parameters.
        $folder = substr($url, 0, strrpos($url, '/') );   // Removeing current file.
        return (isset($_SERVER['HTTPS']) ? "https" : "http") . '://' . $_SERVER['HTTP_HOST'] . $folder. '/oauth2callback.php';
    }
    /**
     * Authenticating to Google using Oauth2
     * Documentation:  https://developers.google.com/identity/protocols/OAuth2
     * Returns a Google client with refresh token and access tokens set. 
     *  If not authencated then we will redirect to request authencation.
     * @return A google client object.
     */
    function getOauth2Client() {
        try {
    
            $client = buildClient();
    
            // Set the refresh token on the client. 
            if (isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
                $client->refreshToken($_SESSION['refresh_token']);
            }
    
            // If the user has already authorized this app then get an access token
            // else redirect to ask the user to authorize access to Google Analytics.
            if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    
                // Set the access token on the client.
                $client->setAccessToken($_SESSION['access_token']);                 
    
                // Refresh the access token if it's expired.
                if ($client->isAccessTokenExpired()) {              
                    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
                    $client->setAccessToken($client->getAccessToken()); 
                    $_SESSION['access_token'] = $client->getAccessToken();              
                }           
                return $client; 
            } else {
                // We do not have access request access.
                header('Location: ' . filter_var( $client->getRedirectUri(), FILTER_SANITIZE_URL));
            }
        } catch (Exception $e) {
            print "An error occurred: " . $e->getMessage();
        }
    }
    

    Then you can check my sample project for more examples here is one on accountsummiries.list