简体   繁体   English

Google Calendar API 服务帐户错误

[英]Google Calendar API Service Account Error

Im getting this error我收到这个错误

{ "error": 
     { "errors": 
         [
            { "domain": "calendar", "reason": "forbiddenForServiceAccounts", "message": "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority." } 
         ], 
         "code": 403,
         "message": "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority."
      } 
}

Already followed this https://developers.google.com/admin-sdk/directory/v1/guides/delegation已经关注这个https://developers.google.com/admin-sdk/directory/v1/guides/delegation

im using this library and im running it on laravel 5.7: https://github.com/spatie/laravel-google-calendar我正在使用这个库并在 laravel 5.7 上运行它: https : //github.com/spatie/laravel-google-calendar

What could be the fix for this.有什么办法可以解决这个问题。 Please help.请帮忙。

Here are the steps to follow to make this work:以下是完成这项工作的步骤:

Enable Domain-Wide Delegation in your service account在您的服务帐户中启用域范围委派

1 - Provide calendar scopes to your service account 1 - 为您的服务帐户提供日历范围

2 - Your user needs to have the role Service Account Token Creator 2 - 您的用户需要具有 Service Account Token Creator 角色

3 - Create a Calendar in the account that you will impersonate 3 - 在您要模拟的帐户中创建一个日历

Service accounts don't have calendars so you have to create your own calendar服务帐户没有日历,因此您必须创建自己的日历

  • Login in https://calendar.google.com/ with the email that you want to own the calendar (I used a different account, not the same that I was going to impersonate, maybe it works using a calendar in the impersonated account)使用您想要拥有日历的电子邮件登录https://calendar.google.com/ (我使用了不同的帐户,与我要模拟的帐户不同,也许它可以在模拟帐户中使用日历)
  • Create a calendar创建日历
  • Share the calendar with the service account with permissions to modify and manage the calendar与有权修改和管理日历的服务帐户共享日历
  • Share the calendar with the account you will impersonate with permissions to modify and manage the calendar与您将模拟的帐户共享日历,并具有修改和管理日历的权限

Create google client创建谷歌客户端

  • Authenticate your service account.验证您的服务帐户。 (I used the JSON Key, I am not sure if other authentication works for this purpose) (我使用了 JSON 密钥,我不确定其他身份验证是否适用于此目的)

Code sample: (I used PHP but I assume that other languages are very similar so you can use this as guideline)代码示例:(我使用 PHP,但我假设其他语言非常相似,因此您可以将其用作指南)

Note that using some email for IMPERSONALIZATION is crucial.请注意,使用一些电子邮件进行 IMPERSONALIZATION 至关重要。 Otherwise, the 403 error will remain, use it for authentication, see the Maksym Kalin response for details.否则,将保留 403 错误,将其用于身份验证,有关详细信息,请参阅 Maksym Kalin 响应。

$google_client = new Google_Client();
$google_client->setAuthConfig($LOCATION_OF_JSON_KEY);
$google_client->setAccessType( 'offline' );
$google_client->setSubject('EmailToImpersonate@SomeAddress.com');
$google_client->setApplicationName("YourApplicationName");
$google_client->setScopes([\Google_Service_Calendar::CALENDAR, \Google_Service_Calendar::CALENDAR_EVENTS]);

Create Event with people invited :) and Enjoy!与受邀的人一起创建活动:) 并享受!

Note: With this approach you can create events and invite people to it.注意:通过这种方法,您可以创建事件并邀请人们加入。 Keep in mind the limits of the G Suite https://support.google.com/a/answer/2905486 so if you want to create many events you will need to have a pool of service accounts with a pool of calendars.请记住 G Suite https://support.google.com/a/answer/2905486的限制,因此如果您想创建许多事件,您需要拥有一个带有日历池的服务帐户池。

The purpose of granting domain-wide authority to a Service Account is for these accounts to be able to access data on behalf of users in the domain.向服务帐户授予域范围权限的目的是让这些帐户能够代表域中用户访问数据。

If you grant it domain-wide authority but are not "impersonating" any account, the Service Account is acting as if you hadn't granted this authority: it is trying to access its own Calendars.如果您授予它域范围的权限但没有“模拟”任何帐户,则服务帐户的行为就好像您没有授予此权限:它正在尝试访问自己的日历。

When the Service Account impersonates another user in the domain (that is, when it acts on behalf of the user), the Service Account can access the resources this user can access.当服务帐户模拟域中的另一个用户时(即,当它代表用户行事时),服务帐户可以访问该用户可以访问的资源。

To impersonate another user, you have to specify the user's email address.要冒充其他用户,您必须指定用户的电子邮件地址。 In my case, I use Node.JS library and my impersonation code looks like this:就我而言,我使用 Node.JS 库,我的模拟代码如下所示:

const auth = new google.auth.JWT(
  config.client_email,
  null,
  config.private_key,
  ["https://www.googleapis.com/auth/calendar.events"],
  "!!! user email to impersonate !!!!",
);

What is more, in case you need to fill attendees[] array, you have to authorize the service account to send emails.更重要的是,如果您需要填写参加者[]数组,您必须授权服务帐户发送电子邮件。 Because you get unauthorized error.因为你得到了未经授权的错误。

To do it you need to add https://www.googleapis.com/auth/gmail.send scope on your G Suite domain's Admin console.为此,您需要在 G Suite 域的管理控制台上添加https://www.googleapis.com/auth/gmail.send范围。

You can find more here: https://issuetracker.google.com/issues/14170493您可以在此处找到更多信息: https : //issuetracker.google.com/issues/14170493

Just for information仅供参考

In my case, on Node.js, i followed intructions from @Anathorn, but i kept getting就我而言,在 Node.js 上,我遵循了@Anathorn 的指示,但我一直得到

Service accounts cannot invite attendees without Domain-Wide Delegation of Authority服务帐户不能在没有域范围授权的情况下邀请与会者

then i add on my auth line the email what should i supplant, and it worked.然后我在我的身份验证行添加了我应该替换的电子邮件,并且它起作用了。

const auth = new google.auth.JWT(
    CREDENTIALS.client_email,`
    null,
    CREDENTIALS.private_key,
    SCOPES,
    "admin@domain.com",
    "12345678987654321"
);

For anyone else that may be running into this issue, for me it was a combination of Anathorn's answer and Maksym Kalin's answer.对于可能遇到这个问题的任何其他人,对我来说,这是 Anathorn 的回答和 Maksym Kalin 的回答的结合。 It was because I was not impersonating the users email address.这是因为我没有冒充用户的电子邮件地址。

A user previously has tried to commit the same library you are using (I am using it too), but it was declined by the repo owner (how sad)一个用户之前曾尝试提交您正在使用的同一个库(我也在使用它),但被 repo 所有者拒绝了(多么悲伤)

https://github.com/spatie/laravel-google-calendar/pull/97 https://github.com/spatie/laravel-google-calendar/pull/97

Anyway, his code here was how I fixed it on my end.无论如何,他在这里的代码是我最终修复它的方式。

Good luck for anyone else who has this issue, its been a pain in my ass for far too long.祝其他遇到这个问题的人好运,这让我痛苦太久了。

For those using the googleapis-nodejs-client library a solution was brought on a issue in the google-auth-library-nodejs github page .对于那些使用 googleapis-nodejs-client 库的人,在 google-auth-library-nodejs github page 中的一个问题上提出了解决方案。

Doing all conf steps from @Anathorn and logging the service account this way worked for me :从@Anathorn 执行所有 conf 步骤并以这种方式记录服务帐户对我有用:

const auth = new google.auth.GoogleAuth({
keyFile: './service.json',
scopes: [
  'https://www.googleapis.com/auth/calendar',
  'https://www.googleapis.com/auth/calendar.events'
],
clientOptions: {
  subject: 'email@email.com'
},

}); });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM