How to set up golang client for Google Calendar APIs using a service account

huangapple go评论103阅读模式
英文:

How to set up golang client for Google Calendar APIs using a service account

问题

我看到了很多关于为用户使用Google API客户端的文档,但很少有关于使用服务帐号的文档。这不是代表用户,我只是想使用客户端ID和客户端密钥来使Calendar API的客户端工作,这些信息将通过环境变量提供给我(我更喜欢不从文件中读取)。

以下是我目前的代码:

package main

import (
  "context"

  clientCredentials "golang.org/x/oauth2/clientcredentials"
  google "golang.org/x/oauth2/google"
  calendar "google.golang.org/api/calendar/v3"
  apiOption "google.golang.org/api/option"
)

func main() {
  config := &clientCredentials.Config{
    ClientID:     "<my_id>",
    ClientSecret: "-----BEGIN PRIVATE KEY-----\n...",
    TokenURL:     google.Endpoint.TokenURL,
  }
  ctx := context.Background()
  client := config.Client(ctx)
  service, _ := calendar.NewService(ctx, apiOption.WithHTTPClient(client))
  
  calendarList, err := service.CalendarList.List().Do()
}

但是我得到了以下错误:

Get "https://www.googleapis.com/calendar/v3/users/me/calendarList?alt=json&prettyPrint=false": oauth2: cannot fetch token: 400 Bad Request
Response: {
  "error": "unsupported_grant_type",
  "error_description": "Invalid grant_type: client_credentials"
}

非常感谢您的帮助!我对Golang、Oauth2和Google API都很新 How to set up golang client for Google Calendar APIs using a service account

英文:

I've seen lots of documentation on Google API clients for users, but very little on using a service account. This isn't on behalf of a user, I'm just trying to get a client working with the Calendar APIs using a client ID and client secret, which would be provided via environment variables for me (I'd prefer to not read from a file).

Here's what I have so far:

package main

import (
  &quot;context&quot;

  clientCredentials &quot;golang.org/x/oauth2/clientcredentials&quot;
  google &quot;golang.org/x/oauth2/google&quot;
  calendar &quot;google.golang.org/api/calendar/v3&quot;
  apiOption &quot;google.golang.org/api/option&quot;
)

func main() {
  config := &amp;clientCredentials.Config{
    ClientID:     &quot;&lt;my_id&gt;&quot;,
	ClientSecret: &quot;-----BEGIN PRIVATE KEY-----\n...&quot;,
	TokenURL:     google.Endpoint.TokenURL,
  }
  ctx := context.Background()
  client := config.Client(ctx)
  service, _ := calendar.NewService(ctx, apiOption.WithHTTPClient(client))
  
  calendarList, err := service.CalendarList.List().Do()
}

But I'm getting the following error:

Get &quot;https://www.googleapis.com/calendar/v3/users/me/calendarList?alt=json&amp;prettyPrint=false&quot;: oauth2: cannot fetch token: 400 Bad Request
Response: {
  &quot;error&quot;: &quot;unsupported_grant_type&quot;,
  &quot;error_description&quot;: &quot;Invalid grant_type: client_credentials&quot;
}

Any help here is greatly appreciated! I'm new to Golang, Oauth2, and Google APIs How to set up golang client for Google Calendar APIs using a service account

答案1

得分: 1

我相信你的目标如下。

  • 你想使用golang使用服务帐户访问Google日历。

在这种情况下,以下修改如何?

修改后的脚本:

package main

import (
	"context"
	"fmt"

	calendar "google.golang.org/api/calendar/v3"
	"google.golang.org/api/option"
)

func main() {
	ctx := context.Background()
	v := `{"type": "service_account", "private_key": "-----BEGIN PRIVATE KEY-----\n###\n-----END PRIVATE KEY-----\n", "client_email": "###"}`
	service, _ := calendar.NewService(ctx, option.WithCredentialsJSON([]byte(v)))
	calendarList, _ := service.CalendarList.List().Do()
	fmt.Println(calendarList)
}
  • 如果你想使用包含凭据信息的文件,请按以下方式进行修改。

      service, _ := calendar.NewService(ctx, option.WithCredentialsFile(credentialFile))
    

注意:

参考资料:

英文:

I believe your goal is as follows.

  • You want to access Google Calendar using the service account with golang.

In this case, how about the following modification?

Modified script:

package main

import (
	&quot;context&quot;
	&quot;fmt&quot;

	calendar &quot;google.golang.org/api/calendar/v3&quot;
	&quot;google.golang.org/api/option&quot;
)

func main() {
	ctx := context.Background()
	v := `{&quot;type&quot;: &quot;service_account&quot;, &quot;private_key&quot;: &quot;-----BEGIN PRIVATE KEY-----\n###\n-----END PRIVATE KEY-----\n&quot;, &quot;client_email&quot;: &quot;###&quot;}`
	service, _ := calendar.NewService(ctx, option.WithCredentialsJSON([]byte(v)))
	calendarList, _ := service.CalendarList.List().Do()
	fmt.Println(calendarList)
}
  • If you want to use the file including the credential information, please modify it as follows.

      service, _ := calendar.NewService(ctx, option.WithCredentialsFile(credentialFile))
    

Note:

References:

答案2

得分: 0

@Tanaike的答案让我找到了正确的方向。这是我最终使用的代码:

package main

import (
	"context"
	"encoding/json"
	"fmt"

	googleOauth "golang.org/x/oauth2/google"
	calendar "google.golang.org/api/calendar/v3"
	apiOption "google.golang.org/api/option"
)

var service *calendar.Service

// 注意,一些字段是可选的:
type GoogleAuthConfig struct {
	Type                string `json:"type"`
	ProjectID           string `json:"project_id,omitempty"`
	ClientEmail         string `json:"client_email"`
	ClientID            string `json:"client_id,omitempty"`
	ClientSecret        string `json:"private_key"`
	ClientSecretID      string `json:"private_key_id,omitempty"`
	AuthURL             string `json:"auth_uri,omitempty"`
	TokenURL            string `json:"token_uri,omitempty"`
	AuthProviderCertURL string `json:"auth_provider_x509_cert_url,omitempty"`
	ClientCertURL       string `json:"client_x509_cert_url,omitempty"`
}

func main() {
	authConfig := GoogleAuthConfig{
		Type:         "service_account",
		ClientEmail:  "account123@project-456.iam.gserviceaccount.com",
		ClientID:     "1234",
		ClientSecret: "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
		AuthURL:      googleOauth.Endpoint.AuthURL,
		TokenURL:     googleOauth.Endpoint.TokenURL,
	}
	authConfigJson, err := json.Marshal(authConfig)

	ctx := context.Background()
	service, err = calendar.NewService(ctx, apiOption.WithCredentialsJSON([]byte(authConfigJson)))
}

注意我不需要配置域委派或模拟用户在将服务帐号添加到日历后这个代码就可以正常工作

在将帐号电子邮件添加到日历后服务帐号仍然需要接受日历邀请可以使用以下代码完成

entry := calendar.CalendarListEntry{Id: calendarID}
service.CalendarList.Insert(&entry).Do()

请注意,这是你提供的代码的翻译版本。如果有任何问题,请告诉我。

英文:

The answer from @Tanaike got me on the right track. This is what I ended up using:

package main
import (
&quot;context&quot;
&quot;encoding/json&quot;
&quot;fmt&quot;
googleOauth &quot;golang.org/x/oauth2/google&quot;
calendar &quot;google.golang.org/api/calendar/v3&quot;
apiOption &quot;google.golang.org/api/option&quot;
)
var service *calendar.Service
// Note that some of the fields are optional:
type GoogleAuthConfig struct {
Type                string `json:&quot;type&quot;`
ProjectID           string `json:&quot;project_id,omitempty&quot;`
ClientEmail         string `json:&quot;client_email&quot;`
ClientID            string `json:&quot;client_id,omitempty&quot;`
ClientSecret        string `json:&quot;private_key&quot;`
ClientSecretID      string `json:&quot;private_key_id,omitempty&quot;`
AuthURL             string `json:&quot;auth_uri,omitempty&quot;`
TokenURL            string `json:&quot;token_uri,omitempty&quot;`
AuthProviderCertURL string `json:&quot;auth_provider_x509_cert_url,omitempty&quot;`
ClientCertURL       string `json:&quot;client_x509_cert_url,omitempty&quot;`
}
func main() {
authConfig := GoogleAuthConfig{
Type:         &quot;service_account&quot;,
ClientEmail:  &quot;account123@project-456.iam.gserviceaccount.com&quot;,
ClientID:     &quot;1234&quot;,
ClientSecret: &quot;-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n&quot;,
AuthURL:      googleOauth.Endpoint.AuthURL,
TokenURL:     googleOauth.Endpoint.TokenURL,
}
authConfigJson, err := json.Marshal(authConfig)
ctx := context.Background()
service, err = calendar.NewService(ctx, apiOption.WithCredentialsJSON([]byte(authConfigJson)))
}

Note that I didn't have to configure domain-wide delegation or impersonate a user; this worked fine after I added the service account to the calendar.

Service accounts still need to accept calendar invites after you add the account email to the calendar. This can be done with the following:

entry := calendar.CalendarListEntry{Id: calendarID}
service.CalendarList.Insert(&amp;entry).Do()

huangapple
  • 本文由 发表于 2023年2月1日 07:28:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75304188.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定