Ошибка API учетной записи службы при получении маркера доступа

# #google-cloud-platform #google-developers-console #google-people-api

Вопрос:

Я тестирую API google people для нашего веб-приложения. Шаги:

  • Я создал новый проект в консоли Google (https://console.cloud.google.com/)
  • Я включил API для людей
  • Я создал необходимые учетные данные — веб-клиент для своего приложения и ключ API
  • Я создал учетную запись службы с ключом p12 для запросов от сервера к серверу и включил «Делегирование домена Google Workspace по всему домену».
  • Я настроил экран согласия OAuth с областями, необходимыми для авторизации в Google и получения доступа к API пользователей: /auth/userinfo.email /auth/userinfo.профиль /авторизация/контакты /авторизация/контакты.только для чтения
  • Затем мой PHP-скрипт с помощью «PHP-клиента Google API» делает перенаправляющую ссылку на экран согласия и возвращает код для токена доступа с веб-клиентом:
 <?php

$client = new Google_Client();

$client->setAccessType('online'); // default: offline
$client->setApplicationName('My Project xxxxx');
$client->setClientId('999999999999-qwertysdfhwe9uriiiiiiiiiiiiiiiii.apps.googleusercontent.com');
$client->setClientSecret('GOCSPX-hhhhhhhhhhhhhhhhhhhhhhhhhhhh');                
$client->setDeveloperKey('AIzafffffffffffffffffffffffffffffffffff'); // API key

$client->setState('subdomain.myapp.com');

$scriptUri = 'https://oauth.myapp.com/auth.php';
$client->setRedirectUri($scriptUri);

$client->addScope('https://www.googleapis.com/auth/userinfo.email');
$client->addScope('https://www.googleapis.com/auth/userinfo.profile');
$client->addScope('https://www.googleapis.com/auth/contacts');
                
$auth_url = $client->createAuthUrl();

header('Location: '.$auth_url);

?>
 

Этот код перенаправляет на экран аутентификации Google, затем я вхожу в систему с помощью Google и утверждаю области. Google перенаправляет меня обратно в мое приложение, и теперь у меня есть маркер доступа, соответствующие области и электронная почта аутентифицированного пользователя.

На следующем шаге у меня огромные проблемы — запрос от сервера к серверу, чтобы получить маркер доступа для API людей

 function base64_url_encode($input) {
    return str_replace('=', '', strtr(base64_encode($input), ' /', '-_'));
}

$iat = time();      

$url = "https://www.googleapis.com/oauth2/v4/token";        

$scope = 'https://www.googleapis.com/auth/contacts';

$jwt_data = array(
    'iss' => '111111111111111111111', // My service account ID
    'aud' => $url,
    'scope' => $scope,
    'exp' => $iat   3600,
    'iat' => $iat,
    'sub' => 'user@gmail.com', // Email of the user that was autenticated in first step
);

openssl_pkcs12_read(file_get_contents('keyfile.p12'), $certs, 'notasecret');
$header = array('typ' => 'JWT', 'alg' => 'RS256');
$signing_input = base64_url_encode(json_encode($header)) . '.' . base64_url_encode(json_encode($jwt_data));
openssl_sign($signing_input, $signature, $certs['pkey'], 'SHA256');
$jwt = $signing_input . '.' . base64_url_encode($signature);

$data = array(
    "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "assertion" => $jwt
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);

$google_contacts_api_tokens_collection[$use_mailbox] = $response;

return $response;
 

И этот код google возвращает ошибку, которую я не могу исправить, и у меня нет никаких идей.

Текст ошибки: «Клиент не имеет права извлекать токены доступа с помощью этого метода или клиент не авторизован ни для одной из запрошенных областей».

Комментарии:

1. Являются ли пользователи пользователями учетных записей Google (Gmail) или пользователями рабочей области Google? Вы можете выдавать себя только за пользователя второго типа.

Ответ №1:

Ваш код пытается выдать себя за пользователя с помощью учетной записи службы. Для этого требуется разрешить делегирование всего домена. Обходным путем сообщение об ошибке означает, что учетная запись службы не имеет разрешения, поскольку делегирование не включено.

Выполните делегирование полномочий по всему домену Google Workspace

Если пользователь не является частью Google Workspace, вы не можете выдавать себя за пользователя.

Ответ №2:

Да, но я уже пробовал это, и это не помогает. Я настроил области действия для учетной записи службы в рабочей области Google, а также установил флажок «Включить делегирование домена в рабочей области Google» в консоли Google. В Google Workspace я использовал цифровой идентификатор клиента своей учетной записи службы.

А еще я обнаружил один странный момент:

  • Веб-клиент всегда возвращает хороший токен доступа, но когда я запрашиваю токен доступа к учетной записи службы, он хорошо работает только для владельца проекта google console (‘sub’ => ‘project.owner@gmail.com»). И если я запрошу маркер доступа к учетной записи службы для другого пользователя (‘sub’ => ‘project.testuser@gmail.com’) Google также возвращает ту же ошибку: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.