Answer:
为了将方法插入到用户的日历中,您需要用户授予您的应用程序代表他们执行操作的权限。这是使用 Google Cloud Platform (GCP) 项目和 OAuth2 身份验证完成的。
更多信息:
每个代表 Google 帐户用户运行并采取操作的应用程序都必须明确定义其能力范围,以便它无法开始执行用户未授予其执行权限的操作。
例如:如果您授予应用程序创建日历活动的权限,您不希望它能够执行其他操作,例如阅读电子邮件或下载云端硬盘的内容。
为了指定您的应用程序有权执行的操作,它需要向 Google 注册。正如您在问题和评论中已经推断出的那样,连接到 G Suite API 的应用程序所需的客户端 ID 和客户端秘密不仅仅是 Google 帐户的用户名和密码,而是指定的 ID-秘密 ID 对,由 Google 提供,用于识别您的应用程序。
OAuth2:
OAuth2是一个特定的授权框架。该框架定义于RFC 6749 https://www.rfc-editor.org/rfc/rfc6749并列出了用户授权应用程序访问其帐户的流程。授权的限制由授权应用的范围决定,未经用户明确重新授权,不得更改。
在继续之前,有必要在这里定义一些重要术语:
User:
用户就是人;拥有帐户并允许应用程序代表其采取行动的个人。
客户或应用程序:
客户端或应用程序是一个程序,旨在通过连接到服务的 API 通过 HTTP 执行操作。应用程序可以是移动应用程序、Web 应用程序或桌面客户端。
授权服务器:
授权服务器是与存储用户资源的服务器分开的服务器。它验证用户的身份并提供可用于获取资源服务器访问令牌的授权。
资源服务器:
这是存储用户数据的服务器。这可以是从用户信息到文件或电子邮件的任何内容。
授权流程已经有详细记录,但对于这种情况,我们可以将其抽象为以下步骤:
- 应用程序希望代表用户在资源服务器上执行操作。
- 应用程序向用户发出授权请求。这通常显示为应用程序正在访问的帐户的登录页面。
- 用户登录其帐户后会看到一个 OAuth 同意屏幕 - 其中包含应用程序名称及其请求授权的任务列表等信息。这些通常是通用的,并且会说类似的话
See and download all your Google Drive files
or View and edit events on all your calendars
。这可以让用户知道what他们在确认之前就已经授权了。
- 向该申请授予授权。
- 应用程序将获得的授权许可及其分配的客户端凭证提供给授权服务器。
- 在验证用户的授权和客户端的凭据是否正确后,授权服务器返回一个访问令牌,该令牌可用于访问请求和批准的资源。注意:无论您使用哪种语言,这通常都由您的客户端库处理.
- 应用程序现在可以向资源服务器发出请求,提供从授权流程中获得的访问令牌。此时就可以访问允许的资源。
谷歌云平台项目:
一个 GCP 项目,Google 将其视为您的应用程序。您的应用程序的注册需要能够获取您的应用程序需要的客户端 ID 和客户端密钥,以便在授权流程中获取访问令牌。
在里面GCP 控制台 https://console.cloud.google.com/您可以设置应用程序所需的所有必需服务。您希望使用的每个 API 都必须为您的应用程序启用,如下所示有很多带有 API 的 Google 服务 https://developers.google.com/apis-explorer并且默认情况下它们是禁用的。
创建 GCP 项目后,您可以使用 API 库(来自≡ > APIs & Services > Library
左侧的菜单项)来查找并启用 API。请注意,对于您的用例,您将需要启用 Google Calendar API 而不是 CalDAV API。
在获取应用程序的凭据之前,您还需要设置同意屏幕。 OAuth 同意屏幕是您的用户在 OAuth 流程的第一步中将看到的内容:
设置 OAuth 同意屏幕时,您需要提供以下信息:
- 应用程序类型(您的域的公共或内部)
- 应用名称
- 您的应用程序需要的范围(在下一节中解释)
设置同意屏幕后,您可以下载应用程序的客户端凭据。有了这些,您的应用程序就有权作为客户端运行,但每个访问其资源的用户仍然必须给予明确的许可才能允许应用程序这样做。
Scopes:
在单个 API 中,可以有多个访问范围 - 对日历事件进行只读访问与对用户拥有的所有日历进行完全读写访问有很大不同。这就是作用域发挥作用的地方。
范围的定义与其同名;也就是说,范围定义了应用程序对服务的访问范围。即使项目启用了整个 API,并不意味着您需要使用该 API 的所有功能。因此,需要定义范围。
在发出用户授权的初始请求之前,范围是在应用程序本身中定义的。以 C# 为例(取自.NET 日历 API 快速入门 https://developers.google.com/calendar/quickstart/dotnet):
// scopes are defined as an array of strings:
static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
...
UserCredential credential;
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
存储的访问令牌基于调用中定义的范围。如果调用的方法需要与令牌授予访问权限的范围不同的范围,则调用将失败并显示403: Unauthorized
错误。需要将所需的范围添加到应用程序中,删除旧的访问令牌,并且用户需要授予新范围的权限。
服务帐户:
除了普通用户之外,还有另一种特殊类型的 Google 帐户,称为服务帐户。从文档中:
服务帐户是应用程序或虚拟机 (VM) 实例(而不是个人)使用的一种特殊帐户。应用程序使用服务帐户进行授权的 API 调用。
通常,您希望为其执行任务或访问资源的每个用户都需要明确授予您的应用程序这样做的权限。但是,对于 G Suite 域,您可以使用服务帐户域范围的委派 https://developers.google.com/admin-sdk/directory/v1/guides/delegation在没有要求的情况下代表用户完成任务。
服务帐户使用一种特殊类型的服务帐户凭据,可以在 GCP 中创建并在您的应用程序中使用。而不是制作一个UserCredential
对象,一个ServiceAccountCredential
需要哪个不需要最终用户的参与 https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#serviceaccountcredential.
当使用域范围委派代表用户运行服务帐户时,需要在委派凭据中指定用户名,以便应用程序知道要以域中的哪个用户身份运行。如果未提供用户,服务帐户将自行运行代码;这在某些情况下很有用,但通常不会返回错误,因此可能不清楚该操作是为谁运行的。
Note:虽然任何人都可以创建服务帐户,但域范围内的授权只能针对 G Suite 域完成,而不能@gmail.com
地址。所有 Gmail 帐户用户must按照 OAuth 流程的规定,明确授予应用程序代表其运行的权限。
参考:
- 使用 OAuth2 访问 Google API |谷歌身份平台 https://developers.google.com/identity/protocols/oauth2
- RFC 6749 - OAuth2 授权框架 https://www.rfc-editor.org/rfc/rfc6749
- OAuth - 维基百科| #OAuth2 https://en.wikipedia.org/wiki/OAuth#OAuth_2.0
- 谷歌云平台控制台 https://console.cloud.google.com/
- Google API 资源管理器 |谷歌开发者 https://developers.google.com/apis-explorer
- .NET 快速入门 |日历 API |谷歌开发者 https://developers.google.com/calendar/quickstart/dotnet
- 服务帐户 |云 IAM 文档 |谷歌云 https://cloud.google.com/iam/docs/service-accounts
- 执行 G Suite 域范围内的授权 |目录API https://developers.google.com/admin-sdk/directory/v1/guides/delegation
- OAuth 2.0 | .NET 的 API 客户端库 https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth
相关问题:
- 谷歌 API 服务帐户。即使使用域范围委派访问也只能看到服务帐户驱动器 https://stackoverflow.com/questions/60892662/google-api-service-account-can-only-see-service-accounts-drive-even-with-domain/60927643
- 使用 Google Calendar API 和服务帐户创建活动 https://stackoverflow.com/questions/61473708