0

I need to read and write Google contacts with PHP via Google People API. I connect to a Google account:

function get_google_client( array $params ): Google_Client {
    $app_name     = $params['application_name'] ?? 'My App';
    $creds_file   = $params['credentials_file'] ?? 'credentials.json';
    $redirect_uri = $params['redirect_uri'] ?? home_url();
    $access_type  = $params['access_type'] ?? 'offline';
    $scopes       = $params['scopes'] ?? array(
        Google\Service\Oauth2::USERINFO_EMAIL,
        Google\Service\PeopleService::USERINFO_PROFILE,
        Google\Service\PeopleService::CONTACTS,
        Google\Service\PeopleService::CONTACTS_READONLY
    );
    $state        = $params['state'] ?? null;

    $client = new Google_Client();
    $client->setApplicationName( $app_name );
    $client->setAuthConfig( $creds_file );
    $client->setRedirectUri( $redirect_uri );
    $client->setAccessType( $access_type );
    $client->setScopes( $scopes );
    if ( $state ) {
        $client->setState( $state );
    }

    return $client;
} 

$client = get_google_client( array() );
$token = $_SESSION['google_token'] ?? null;

if ( $token ) {
    $client->setAccessToken( $token );
}

if ( $client->isAccessTokenExpired() ) {
    if ( $client->getRefreshToken() ) {
        $client->fetchAccessTokenWithRefreshToken( $client->getRefreshToken() );
    } else {
        $auth_code = filter_input( INPUT_GET, 'code', FILTER_SANITIZE_STRING );

        if ( $auth_code ) {
            $token = $client->fetchAccessTokenWithAuthCode( $auth_code );
            $client->setAccessToken( $token );
        }
    }
}

Authentication works but token expires after 1 hour so I need to refresh it but $client->getRefreshToken() always return null so I can't.

What's wrong?

icolumbro
  • 97
  • 3
  • 17
  • Have you tried saving your access token ````token.json```` into a file? Also, if you cannot get a refresh token, you can reset your authentication manually. I suggest you check the code in the [quickstart page](https://developers.google.com/people/quickstart/php) and add only the required scopes until you encounter a problem. – CMB Nov 08 '21 at 18:39
  • I already tried to save access token in a json file: same problem... – icolumbro Nov 09 '21 at 13:29
  • Does it request authentication manually? Which of the scopes causes the problem? What if you put only the read-only scope ````CONTACTS_READONLY````? – CMB Nov 09 '21 at 14:55
  • Constant [FILTER_SANITIZE_STRING](https://stackoverflow.com/questions/69207368/constant-filter-sanitize-string-is-deprecated) is deprecated. Please stop using it. – Dharman Nov 15 '21 at 12:36

1 Answers1

0

There could be a number of solutions:

  1. Your application does not authenticate manually if the refresh token does not exist. This code segment from the People API Quickstart | PHP should recreate the refresh token.
    // If there is no previous token or it's expired.
    if ($client->isAccessTokenExpired()) {
        // Refresh the token if possible, else fetch a new one.
        if ($client->getRefreshToken()) {
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
        } else {
            // Request authorization from the user.
            $authUrl = $client->createAuthUrl();
            printf("Open the following 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);

            // Check to see if there was an error.
            if (array_key_exists('error', $accessToken)) {
                throw new Exception(join(', ', $accessToken));
            }
        }
  1. If, in any chance, the code forces you to re-authenticate manually every hour, there could be some scopes that are restricted, and thus your application needs verification.

Referring to this Support Article:

Sensitive scopes

Some of the scopes used by the following APIs are considered sensitive; see the API documentation or look for the lock icon in the Cloud Console. If your app requests sensitive scopes, and doesn't meet any of the criteria for an exception (see below), you will need to verify that your app follows the API Services User Data Policy.

For a complete list of Google APIs, see OAuth 2.0 Scopes for Google APIs. To check if scopes are sensitive or restricted, add the scopes to your project via the Google Cloud Console.

CMB
  • 4,950
  • 1
  • 4
  • 16