Search code examples
phpoauth-2.0google-oauthgoogle-analytics-api

How to make Google reporting API refresh the oauth2 access token when it expires?


I am working on an analytics API project and when the access token expires after an hour I get "code:401, Invalid Credentials" and have to unset the php session to be able to re-authenticate. I have read that I should receive a refresh token automatically when first authorized but I'm not seeing it anywhere. I have also tried to set the refresh token manually, having obtained it from the oauth2 playground. How can I make this work? Should the refresh token be stored in $_SESSION initially?

The code in question:

require_once __DIR__ . '/vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig(__DIR__ . '/client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->setAccessType('offline');        
$client->setApprovalPrompt('force');
$client->setIncludeGrantedScopes(true);   
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $analytics = new Google_Service_Analytics($client);

} else {
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Access token in $_SESSION

[access_token] => blahblahblah
[expires_in] => 3600
[scope] => https://www.googleapis.com/auth/analytics.readonly
[token_type] => Bearer
[created] => 1537207944

Solution

  • So, after much digging and tinkering I finally got it to work. I kept seeing reference to

    $client->setAccessType('offline'); 
    

    and

    $client->setApprovalPrompt('force');
    

    being the solution to my problem, but they weren't working for me. It turns out that they need to be added to oauth2callback.php, NOT any other reporting or management files. This was deceiving due to the other files also manipulating the $client object. I'm finally receiving a refresh_token in $_SESSION['access_token'] and it seems to be handling refreshes on it's own now without any further action.