Google OAuth2 с учетной записью службы - указание электронной почты пользователя для действий от имени


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

Я могу успешно добавлять события в свой календарь Google, но не напоминания. Это связано с тем, что события добавляются по электронной почте учетной записи службы (что-то вроде [email protected]), и я должен добавлять напоминания, используя свою учетную запись Gmail, а не учетную запись службы).

К счастью, можно действовать от имени моей учетной записи Gmail. Видеть внизу этой страницы: https://developers.google.com/api-client-library/php/guide/aaa_oauth2_service#using
Он предлагает добавить $cred->sub = "[email protected]";

Но я получаю следующую ошибку при добавлении этого кода:

Исключение Google_auth_exception: Ошибка обновления токена OAuth2, сообщение: '{ "ошибка": "внутренняя ошибка"}'

Я делаю что-то не так, но я не знаю, что, вот мой код ниже:

$applicationName = 'applicationName';
$serviceAccountEmail = '[email protected]';
$serviceAccountKeyPath = __DIR__ . '/xyz-privatekey.p12';
$serviceAccountClientId = 'xyz.apps.googleusercontent.com';

$client = new \Google_Client();
$client->setApplicationName($applicationName);
$service = new \Google_Service_Calendar($client);

if (isset($_SESSION['service_token'])) {
    $client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($serviceAccountKeyPath);
$cred = new \Google_Auth_AssertionCredentials(
    // $serviceAccountName
    $serviceAccountEmail,
    // $scopes array List of scopes
    array('https://www.googleapis.com/auth/calendar'),
    // $privateKey
    $key
);
$client->setClientId($serviceAccountClientId);
$cred->sub = '[email protected]';
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
    $client->getAuth()->refreshTokenWithAssertion(); // fails on this line
}
$_SESSION['service_token'] = $client->getAccessToken();

PS: Если я раскомментирую $cred->sub = '[email protected]';, код не вызовет исключение

Author: Matthew, 2014-05-25

1 answers

Учетная запись службы, выдающая себя за пользователя, применяется только к приложениям Google, см. https://code.google.com/p/google-apps-manager/wiki/GAM3OAuthServiceAccountSetup

Если вы хотите, чтобы ваше приложение получало доступ к календарю любого пользователя, вам следует использовать стандартный поток OAuth2, чтобы получить согласие пользователя и сохранить токен обновления для дальнейшего использования (поскольку вы пытаетесь использовать учетную запись службы, я предполагаю, что это приложение на стороне сервера). Если единственным пользователем являетесь вы сами и вы не планируете распространять вас приложение для кого-либо другого, вы можете жестко закодировать маркер обновления на своем сервере. Вот документация для потока веб-сервера Google OAuth2: https://developers.google.com/accounts/docs/OAuth2WebServer

 2
Author: mengcheng, 2014-05-27 23:38:39