Client is unauthorized to retrieve access tokens using this method - Google calendar php api

Viewed 173

I have read a lot of articles :

Google Calendar API - PHP https://developers.google.com/calendar/quickstart/php

and others.. I want to use the service account, I gave permissions for my calendar, I have downloaded the json key. If I use the code from Google, I got:

missing the required redirect URI

If i use the code:

$client = new Google\Client();
$client->setApplicationName('Gcal');
$client->setAuthConfig($key_file_location);
$client->setScopes([Google_Service_Calendar::CALENDAR]);
$client->setSubject($calendarId);
$client->setAccessType('offline');
$service = new Google_Service_Calendar($client); 

I have:

Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested

I don't have admin.google access, I need to access only my own calendar and delete old events. Please let me know what I am missing.

thank you

2 Answers

I tried to recreate your case and i think i see what's going wrong.

If you are picking "Web server", when creating client configuration:

enter image description here

Then you can use php from example, run script, obtain access token from get variables and give it back to console:

enter image description here

However if you are creating client configuration and using "Web browser", then your script is asking for redirect URI, which you can add to example php:

...
$client = new Google_Client();
$client->setRedirectUri('https://yourdomain.com/somedir');
$client->setApplicationName('Google Calendar API PHP Quickstart');
...

However then you have to go to Google Cloud Platform:

enter image description here

and authorize your domain and your redirect URI. When you run your script now, you will get your access token on redirect site.

Service accounts only with the Google Calendar api if you have set up domain wide delegation from a Google workspace account.

You can get around this by creating a normal web client and authorize your code once and store the refresh token. You can then use the refresh token to access the calendar in the future.

You should probably monitor this solution as the refresh oten can expire in very rare cases. So if it does fail to request a new access token you will have to re authorize the code and get a new refresh token.

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());    // load the stored refresh token.
    return $client;
}

Then before calling the api make sure to check that you dont need a new access token.

if ($client->isAccessTokenExpired()) {
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
Related