Google Admin SDK: у вас нет прав доступа к этому API

Поскольку аутентификация входа в систему Google отключена с прошлой недели, я пытаюсь настроить oAuth 2.0 на учетную запись службы. Мы хотим предоставить пользователям нашего внутреннего веб-приложения возможность выхода из офиса.

Я скачал последний Клиентская библиотека Google API для PHP. в Консоль разработчика Google, Я создал новый проект для своего приложения и создал Service account полномочия. Я также включил службу API: Admin SDK в консоли разработчика.

введите описание изображения здесь

Я предоставил ID пользователя учетной записи доступ к правильным областям (я думаю):
введите описание изображения здесь

Когда я использую пример service-account.php и изменяю детали, я получаю JSON с токеном доступа, но когда я делаю запрос CURL (такой же, как и раньше), чтобы получить настройки электронной почты от пользователя, возникает ошибка "You are not authorized to access this API." происходят.

Мой код:

<?php

include_once "templates/base.php";
require_once realpath(dirname(__FILE__) . '/../src/Google/autoload.php');
$client_id = '124331845-DELETEDPART-hbh89pbgl20citf6ko.apps.googleusercontent.com'; //Client ID
$service_account_name = '124331845-DELETEDPART-89pbgl20citf6ko@developer.gserviceaccount.com'; //Email Address
$key_file_location = 'globaltext-4ce09b20cb73.p12'; //key.p12

$client = new Google_Client();
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://apps-apis.google.com/a/feeds/emailsettings/2.0/'),
$key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}

$aOutput = json_decode($client->getAccessToken());

$strEmailAdresSplit = explode('@', "[email protected]");
$strDomein = $strEmailAdresSplit[1];
$strAlias = $strEmailAdresSplit[0];

$resConnectionJobs = curl_init();
$aHeader = array();
$aHeader[] = 'Authorization: Bearer '.$aOutput->access_token;
$aHeader[] = 'Content-Type: application/atom+xml';

curl_setopt($resConnectionJobs, CURLOPT_URL, "https://apps-apis.google.com/a/feeds/emailsettings/2.0/DOMAIN.EXTENSION/FIRSTNAME.LASTNAME/vacation");
curl_setopt($resConnectionJobs, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($resConnectionJobs, CURLOPT_HTTPHEADER, $aHeader);
curl_setopt($resConnectionJobs, CURLOPT_RETURNTRANSFER, true);
curl_setopt($resConnectionJobs, CURLOPT_HEADER, false);

$oCurlData = curl_exec($resConnectionJobs);

curl_close($resConnectionJobs);
echo $oCurlData;

?>

5

Решение

Вы уверены, что ваши учетные данные в порядке?

Пожалуйста, попробуйте следующую процедуру, чтобы убедиться, что у вас есть правильные учетные данные.

Создание ваших ключей API

Перейти к консоль разработчика и выполните следующие действия:

  • Выберите свой проект
  • Выберите пункт меню «APIs» & Auth»
  • Выберите пункт меню «Зарегистрированное приложение»
  • Зарегистрируйте приложение типа «веб-приложение»
  • Выберите один из следующих вариантов в зависимости от того, какое приложение вы создаете. Языки на стороне сервера должны использовать эту опцию:
    • Ключ для серверных приложений (с IP-блокировкой)

Получение токена доступа & обновить токен

Создайте файл, который содержит следующий код:

<?php

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" => YOUR_CLIENT_ID,
"client_secret" => YOUR_CLIENT_SECRET,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"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);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] === 200) {
header('Content-Type: ' . $info['content_type']);
return $output;
} else {
return 'An error happened';
}
} else {

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

$params = array(
"response_type" => "code",
"client_id" => YOUR_CLIENT_ID,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"scope" => "https://www.googleapis.com/auth/plus.me");

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

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

Теперь замени YOUR_CLIENT_ID а также YOUR_CLIENT_SECRET с вашим идентификатором клиента и секретом клиента.

Убедитесь, что ваш объем правильный. Например, это должно быть https://www.googleapis.com/auth/analytics если вы хотите получить доступ к Google Analytics.

Если вы запустите файл, вы должны получить экран подтверждения OAuth2.

Если вы сейчас нажмете Accept, вы должны получить результат, который выглядит следующим образом:

{
"access_token" : YOUR_ACCESS_TOKEN,
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : YOUR_REFRESH_TOKEN
}

Результат может содержать дополнительные поля, в зависимости от того, на какую область вы претендуете.


Подключение к системам Google в фоновом режиме

После того, как вышеперечисленное заработало, ваше приложение должно реализовать следующий рабочий процесс:

1) Проверьте, содержит ли ваш ввод параметр GET с именем «code». Если присутствует «код», получите новый токен доступа и повторите этот шаг (обновите страницу)
Если «код» отсутствует, перейдите к шагу 2.

2) Проверьте, хранятся ли у вас учетные данные для вашего сервиса. Если учетные данные присутствуют, проверьте, не истек ли ваш токен доступа или скоро истекает. Затем перейдите к шагу 3. Если учетные данные отсутствуют, перейдите к пути авторизации вашей службы, чтобы получить код авторизации, и вернитесь к шагу 1 (убедитесь, что Google перенаправляет на ваш текущий URL).

3) Если требуется обновление, обновите страницу и вернитесь к шагу 1.
Если обновление не требуется, вы готовы сделать то, что вы хотели сделать в первую очередь.


Однако PHP-библиотека Google позаботится о том, чтобы поток oAuth2 для вас. Если вы используете их библиотеку, каждая из трехэтапных процедур выполняется библиотекой, и вы сразу же сможете делать все, что захотите, со службами Google. Я сам использую эту стратегию в моя панель инструментов Google Adwords.

Однако вы можете просто написать свою собственную библиотеку и напрямую подключиться к сервису. Ниже приведен код разработчика из проекта, который я написал несколько месяцев назад. Хотя он не работает «из коробки» (поскольку это контроллер, являющийся частью более крупного приложения), он должен помочь вам понять поток, который библиотека Google берет на себя.

namespace Application;

class Controller_API_Google_Youtube extends Controller_API {
public function read() {
$scope = "https://www.googleapis.com/auth/youtube";
$this->doOauth($scope);
}

function doOauth($scope) {

$oauth2Credentials = JSON_File::load(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json');

$paths = array(
'token' => 'https://accounts.google.com/o/oauth2/token',
'auth' => "https://accounts.google.com/o/oauth2/auth");

$refreshtime = 300;

if (isset($_GET['code'])) {
// Get access code
$query = $_GET;
unset($query['code']);
if (count($query) > 0) {
$query = '?' . http_build_query($query);
} else {
$query = '';
}

$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'url' => $paths['token'],
'returntransfer' => 1,
'post' => true,
'postfields' => array(
'code' => $_GET['code'],
"client_id" => $oauth2Credentials['client_id'],
"client_secret" => $oauth2Credentials['client_secret'],
"redirect_uri" => HTTP_PROTOCOL . URL_PATH . $query,
"grant_type" => "authorization_code")
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$info = $response['maps']->getInfo();
$content = $response['maps']->getContent();
if ($info['http_code'] === 200) {
$output = JSON::decode($content);
$oauth2Credentials[$scope] = array();
$oauth2Credentials[$scope]['expires'] = time() + $output['expires_in'];
$oauth2Credentials[$scope]['access_token'] = $output['access_token'];
$oauth2Credentials[$scope]['refresh_token'] = $output['refresh_token'];
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json', JSON::encode($oauth2Credentials));
header("Location: " . HTTP_PROTOCOL . URL_PATH . $query);
} else {
echo "Something went wrong";
}
} elseif (!isset($oauth2Credentials[$scope])) {
// Get auth code

header("Location: " . $paths['auth'] . '?' . http_build_query(
array(
"response_type" => "code",
"client_id" => $oauth2Credentials['client_id'],
"redirect_uri" => HTTP_PROTOCOL . DOMAIN_PATH,
"scope" => $scope
)
));
} elseif ($oauth2Credentials[$scope]['expires'] - $refreshtime < time()) {
// Refresh access code

$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'url' => $paths['token'],
'returntransfer' => 1,
'post' => true,
'postfields' => array(
"client_id" => $oauth2Credentials['client_id'],
"client_secret" => $oauth2Credentials['client_secret'],
"refresh_token" => $oauth2Credentials[$scope]['refresh_token'],
"grant_type" => "refresh_token")
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$info = $response['maps']->getInfo();
$content = $response['maps']->getContent();
if ($info['http_code'] === 200) {
$output = JSON::decode($response['maps']->getContent());
$oauth2Credentials[$scope]['expires'] = time() + $output['expires_in'];
$oauth2Credentials[$scope]['access_token'] = $output['access_token'];
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json', JSON::encode($oauth2Credentials));
$this->read();
} else {
$this->output = array("error" => "Something went wrong");
}
} else {
$this->doSomethinguseful($oauth2Credentials, $scope);
}
return $this;
}


function doSomethinguseful($oauth2Credentials, $scope) {
// https://developers.google.com/youtube/v3/sample_requests?hl=nl
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'useragent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13',
'url' => 'https://www.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true',
'returntransfer' => true,
'httpheader' => array(
'Authorization: Bearer ' . $oauth2Credentials[$scope]['access_token'],
'Accept-Encoding: gzip, deflate'
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$content = $response['maps']->getContent();
$this->output = JSON::decode(gzdecode($content));
}
}
1

Другие решения

Похоже, у вас тоже может быть проблема.

Призыв к Google_Auth_AssertionCredentials на самом деле требует больше параметров, чем вы посылаете для работы с учетной записью службы. (По крайней мере, так и было в моем случае.)

Вам нужно передать достаточно параметров, чтобы включить подпрограмму (какого пользователя выполнять действия из-за).

Без этого мне всегда отказывали в доступе. Это явно не очевидно, так как в библиотеку php даже была добавлена ​​функция, loadServiceAccountJson, который должен установить клиентское соединение с учетной записью службы, но разрывается, потому что он также не устанавливает sub.

Смотрите рабочий код здесь: Google php клиентская библиотека loadServiceAccountJson не работает — исправлено

-1

По вопросам рекламы [email protected]