Q:

Google Access Token without authorization

I'm developing module for obtaining additional data from google analytics account. To get this data Google requires access_token. 
This is what I've managed so far
if (isset($_GET['code'])) {
    // try to get an access token
    $code = $_GET['code'];
    $url = 'https://accounts.google.com/o/oauth2/token';
    $params = array(
        "code" => $code,
        "client_id" => "559825975819-881lg83vs8feo70v5unqa8kfoijuvfnn.apps.googleusercontent.com",
        "client_secret" => "vj4UNNItAJocX4RkNaD_3DQ4",
        "redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
        "access_type" => "offline",
        "grant_type" => "authorization_code"
    );

    $ch = curl_init();
    curl_setopt($ch, constant("CURLOPT_" . 'URL'), $url);
    curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
    curl_setopt($ch, constant("CURLOPT_" . 'POSTFIELDS'), $params);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);
 $data = (json_decode($output, true));

 $access_token_var = $data['access_token'];

  echo $access_token_var;

} else {

    $url = "https://accounts.google.com/o/oauth2/auth";

    $params = array(
        "response_type" => "code",
        "client_id" => "559825975819-881lg83vs8feo70v5unqa8kfoijuvfnn.apps.googleusercontent.com",
        "redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
        "scope" => "https://www.googleapis.com/auth/analytics",
        "access_type" => "offline",
        "approval_prompt" => "force"
    );

    $request_to = $url . '?' . http_build_query($params);

    header("Location: " . $request_to);
}

And I'm getting access_token, it is echoing in needed variable. But I want to obtain analytics additional data in background process (for example, while client making order and clicking order button), but everytime I need new access_token, i need to authorize with my google account, and therefore, every client on web site needs to do this, despite the fact, that I set up  "access_type" => "offline". What's wrong? Or is it something wrong with my API app?

A:

The access token expire after a short amount of time. You need to refresh the access token every time it expires.
https://developers.google.com/identity/protocols/OAuth2WebServer

Access tokens periodically expire. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.

You don't have to refresh to access token yourself. You can use Goggle php library https://github.com/googleapis/google-api-php-client so it can refresh the token automatically. Here is an example taken from Google website.
$client = new Google_Client();
$client->setAuthConfig('client_secrets.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $drive = new Google_Service_Drive($client);
  $files = $drive->files->listFiles(array())->getItems();
  echo json_encode($files);
} else {
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

If you don't want or can't use Google Php library, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token. You can use the same way you get the access token via curl but with different params.
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=<your_client_id>&
client_secret=<your_client_secret>&
refresh_token=<refresh_token>&
grant_type=refresh_token

