带有服务帐户的Google OAuth2 - 指定要代表的用户电子邮件

时间:2014-05-25 00:20:04

标签: oauth-2.0 google-api google-oauth google-api-php-client

我正在尝试以编程方式在Google日历上添加活动和提醒。 我使用的是服务帐户

我可以成功将事件添加到我的Google日历,但不能添加提醒。这是因为事件是由服务帐户电子邮件(类似于xyz@developer.gserviceaccount.com)添加的,我应该使用我的Gmail帐户而不是服务帐户添加提醒。

幸运的是,可以代表我的Gmail帐户行事。见本页底部: https://developers.google.com/api-client-library/php/guide/aaa_oauth2_service#using
它建议添加$cred->sub = "emailaddress@yourdomain.com";

但是在添加此代码时出现以下错误:

  

Google_Auth_Exception:刷新OAuth2令牌时出错,消息:'{   “错误”:“internal_failure”}'

我做错了但我不知道是什么,这是我的代码:

$applicationName = 'applicationName';
$serviceAccountEmail = 'xyzg@developer.gserviceaccount.com';
$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 = 'myEmail@gmail.com';
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
    $client->getAuth()->refreshTokenWithAssertion(); // fails on this line
}
$_SESSION['service_token'] = $client->getAccessToken();

PS:如果我取消注释$cred->sub = 'myEmail@gmail.com';,代码不会抛出异常

1 个答案:

答案 0 :(得分:2)

冒充用户的服务帐户仅适用于Google Apps,请参阅https://code.google.com/p/google-apps-manager/wiki/GAM3OAuthServiceAccountSetup

如果您希望自己的应用访问任何用户的日历,则应使用标准OAuth2流程获取用户的同意并存储刷新令牌以备将来使用(因为您尝试使用服务帐户我认为这是服务器端应用程序)。如果唯一的用户是您自己并且您不打算将应用程序分发给其他任何人,则可以在服务器中对刷新令牌进行硬编码。 以下是Google OAuth2网络服务器流程的文档:https://developers.google.com/accounts/docs/OAuth2WebServer