-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Client is unauthorized to retrieve access tokens using this method" w/ Service Account #2214
Description
PROBLEM / CAUSE: I am using google-php-api-client to create calendar event, with service account and set the subject, subject email address is my admin account, with out subject this is working but when i am set subject this is not working and given error Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested,
When i am calling throw google API this is working properly
API Calling code is :
define('CALENDAR_ID', <claendar_id>);
/*********************** Start: Create access Token***********************************/
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function getJwtAssertion($private_key_file)
{
$json_file = file_get_contents($private_key_file);
$info = json_decode($json_file);
$private_key = $info->{'private_key'};
//{Base64url encoded JSON header}
$jwtHeader = base64url_encode(json_encode(array(
"alg" => "RS256",
"typ" => "JWT"
)));
//{Base64url encoded JSON claim set}
$now = time();
$jwtClaim = base64url_encode(json_encode(array(
"iss" => <serviceaccount>,
"sub" => <admin_email_address>,
"scope" => "https://www.googleapis.com/auth/calendar",
"aud" => "https://www.googleapis.com/oauth2/v4/token",
"exp" => $now + 3600,
"iat" => $now
)));
$data = $jwtHeader.".".$jwtClaim;
// Signature
$Sig = '';
openssl_sign($data,$Sig,$private_key,'SHA256');
$jwtSign = base64url_encode($Sig);
$jwtAssertion = $data.".".$jwtSign;
return $jwtAssertion;
}
function getGoogleAccessToken($private_key_file)
{
$result = [
'success' => false,
'message' => '',
'token' => null
];
if(!file_exists($private_key_file)){
$result['message'] = 'Google json key file missing!';
return $result;
}
$jwtAssertion = getJwtAssertion($private_key_file);
try {
$payload = [
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwtAssertion
];
$url = 'https://oauth2.googleapis.com/token';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if($http_code != 200){
$result['message'] = 'Error : Failed to access token';
} else {
$result['token'] = $data['access_token'];
$result['success'] = true;
}
} catch (RequestException $e) {
$result['message'] = $e->getMessage();
}
return $result;
}
$KEY_FILE_LOCATION = __DIR__.'/key_file.json';
$googleToken = getGoogleAccessToken($KEY_FILE_LOCATION);
/*********************** End Create access Token***********************************/
if(isset($googleToken['token'])){
$access_token = $googleToken['token'];
getCalendarDetails($access_token);
}
function getCalendarDetails($access_token) {
$url_events = 'https://www.googleapis.com/calendar/v3/calendars/claendar_id';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_events);
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token, 'Content-Type: application/json'));
$data = curl_exec($ch);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
echo "<pre>";
print_r($data);
die();
}
But i am set the subject with Google php client is not working
My code is :
require_once 'vendor/autoload.php';
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/clanedar_key.json');
$calendarId = <calendar_id>;
$client = new Google_Client();
// use the application default credentials
$client->useApplicationDefaultCredentials();
$client->setSubject("admin_gmail_account");
$client->addScope([Google_Service_Calendar::CALENDAR_EVENTS, Google_Service_Calendar::CALENDAR]);
$service = new Google_Service_Calendar($client);
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c', strtotime('2022-01-28 9:00am -1 minute')),
'timeMax' => date('c', strtotime('2022-02-28 10:00am +1 minute')),
);
$results = $service->events->listEvents($calendarId, $optParams);
foreach ($results->getItems() as $event) {
$start = $event->start->dateTime;
$start = !$start ? $event->start->date : $start;
$end = $event->end->dateTime;
printf($event->getSummary() . "<br>" . $start . "<br>" .$end. "<br>". $event->hangoutLink ."<br><br>");
}
Seen Error :
Fatal error: Uncaught Google\Service\Exception: { "error": "unauthorized_client", "error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested." } in /var/www/html/google-api-php-client-main/src/Http/REST.php:128 Stack trace: #0 /var/www/html/google-api-php-client-main/src/Http/REST.php(103): Google\Http\REST::decodeHttpResponse() googleapis/google-api-dotnet-client#1 [internal function]: Google\Http\REST::doExecute() googleapis/google-api-dotnet-client#2 /var/www/html/google-api-php-client-main/src/Task/Runner.php(182): call_user_func_array() googleapis/google-api-dotnet-client#3 /var/www/html/google-api-php-client-main/src/Http/REST.php(66): Google\Task\Runner->run() googleapis/google-api-dotnet-client#4 /var/www/html/google-api-php-client-main/src/Client.php(918): Google\Http\REST::execute() googleapis/google-api-dotnet-client#5 /var/www/html/google-api-php-client-main/src/Service/Resource.php(238): Google\Client->execute() googleapis/google-api-dotnet-client#6 /var/www/html/google-api-php-client-main/vendor/google/apiclient-services/src/Calendar/Resource/Events.php(271): Google\Service\Resource->call() googleapis/google-api-dotnet-client#7 /var/www/html/google-api-php-c in /var/www/html/google-api-php-client-main/src/Http/REST.php on line 128