Google cloud platform 如何从GCE VM命令行设置使用Gmail API的凭据?

Google cloud platform 如何从GCE VM命令行设置使用Gmail API的凭据?,google-cloud-platform,gmail-api,Google Cloud Platform,Gmail Api,我正试图让我在GCE上的Linux虚拟机访问我的Gmail帐户,以便发送电子邮件 我找到了这篇文章,它阅读了一些Gmail帐户信息(这很有用,因为我只想测试我的连接) 但是,我不确定需要设置哪些凭据,如设置和使用时: 服务帐户:我收到以下消息ValueError:客户端机密必须用于web或已安装的应用程序。 Web应用程序类型的OAuth客户端ID:代码运行良好,但在尝试首次授权应用程序访问时,我收到以下消息: 错误400:重定向\u uri\u不匹配 请求中的重定向URI,http://l

我正试图让我在GCE上的Linux虚拟机访问我的Gmail帐户,以便发送电子邮件

我找到了这篇文章,它阅读了一些Gmail帐户信息(这很有用,因为我只想测试我的连接)

但是,我不确定需要设置哪些凭据,如设置和使用时:

  • 服务帐户:我收到以下消息
    ValueError:客户端机密必须用于web或已安装的应用程序。

  • Web应用程序类型的OAuth客户端ID:代码运行良好,但在尝试首次授权应用程序访问时,我收到以下消息:

  • 错误400:重定向\u uri\u不匹配 请求中的重定向URI,http://localhost:60443/,与为OAuth客户端授权的不匹配。要更新授权重定向URI,请访问:

  • 桌面类型的OAuth客户端ID:代码运行良好,但在尝试首次授权应用程序访问时,我收到以下消息:
  • 本地主机连接已被拒绝

    有人知道如何正确设置,以及我是否遗漏了什么吗

    谢谢


    [nov17]

    在将gmail作用域添加到虚拟机的作用域后,我运行了python脚本,出现了以下错误:

        Traceback (most recent call last):
      File "quickstart2.py", line 29, in <module>
        main()
      File "quickstart2.py", line 18, in main
        results = service.users().labels().list(userId="107628233971924038182").execute()
      File "/home/lucasnunesfe9/.local/lib/python3.7/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper
        return wrapped(*args, **kwargs)
      File "/home/lucasnunesfe9/.local/lib/python3.7/site-packages/googleapiclient/http.py", line 915, in execute
        raise HttpError(resp, content, uri=self.uri)
    googleapiclient.errors.HttpError: <HttpError 400 when requesting https://gmail.googleapis.com/gmail/v1/users/107628233971924038182/labels?alt=json returned "Precondition check failed.">
    
    “第一授权步骤”中是否需要任何手动程序


    PS:强调我已经将我的服务帐户启用为“G套件域范围授权”。此操作生成了一个OAuth 2.0客户端ID,该ID正在python脚本中使用(变量userId)。

    就我个人而言,我从未理解过这个示例。我认为它太旧了(甚至兼容Python 2.6!!)

    不管怎样,你可以忘记第一部分,获得这样的凭证

    from googleapiclient.discovery import build
    import google.auth
    
    # If modifying these scopes, delete the file token.pickle.
    SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
    
    def main():
    
        creds, project_id = google.auth.default(scopes=SCOPES)
        service = build('gmail', 'v1', credentials=creds)
    
        # Call the Gmail API
        results = service.users().labels().list(userId='me').execute()
        labels = results.get('labels', [])
    
        if not labels:
            print('No labels found.')
        else:
            print('Labels:')
            for label in labels:
                print(label['name'])
    
    if __name__ == '__main__':
        main()
    
    但是,由于您将使用服务帐户访问您的GMAIL帐户,因此您必须使用您想要的ID更改用户ID,并从GSuite管理控制台访问服务帐户,才能访问GMAIL API


    要实现这一点,您需要授予VM服务帐户的作用域。停止VM,运行此(长)命令,然后再次启动VM。命令:

    • 获取VM的当前作用域(并清除/格式化它们)
    • 添加gmail范围
    • 将作用域设置为VM(这是一个BETA命令)
    gcloud beta计算实例设置范围--区域\
    --范围=https://www.googleapis.com/auth/gmail.readonly,\
    $(gcloud计算实例描述--zone\
    --格式为json | jq-c).serviceAccounts[0].作用域“|sed-E”s/\[(.*)\]/\1/g”| sed-E“s/\”//g)
    
    尝试一下。使用默认凭据模式->
    凭据,project_id=google.auth.default()
    。考虑正确地定义您的计算引擎。如果您有问题,请在问题中添加更多详细信息,我将向您提供完整答案。我不确定您的建议是否适合脚本(我已将其添加到我的问题中)。请参阅这段代码:“flow=InstalledAppFlow.from_client_secrets_file('credentials.json',SCOPES)”…请求包含客户端机密的文件路径。此外,已通知此脚本适用于“本例中的授权流是为命令行应用程序设计的”“。所以,我在虚拟机中努力这么做似乎很奇怪。为了加强这一点,这个虚拟机是在谷歌云引擎中实例化的。您好@guillaume,我尝试了您建议的脚本,并且我已经启用了我的服务帐户,使其具有G套件域范围的委派访问权限(我在脚本中使用了我的用户ID)。但是,我收到了以下消息:
    GoogleAppClient.errors.HttpError:
    。我在当前目录中看不到我的tocken.pickle文件。您知道这有助于我们了解发生了什么吗?正如我在前面的评论中提到的,您的计算引擎服务帐户的范围很重要。我用命令。更改您的虚拟机名称和区域。我用我的分析/结果更新了您的答案…不幸的是,它仍然不正确,双引号破坏了命令。我更新了脚本。但是,我可以接受您的编辑,因为您建议的范围不正确,并且您失去了当前虚拟机的所有范围。请告诉我如果现在更好。您的脚本现在还可以(它将gmail作用域附加到VM的作用域列表中)。但是,我仍然收到一个HttpError,它与第一个不同(
    GoogleAppClient.errors.HttpError:
    )。我用进一步的信息更新了我的原始问题
    {
      "error": {
        "code": 401,
        "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
        "errors": [
          {
            "message": "Login Required.",
            "domain": "global",
            "reason": "required",
            "location": "Authorization",
            "locationType": "header"
          }
        ],
        "status": "UNAUTHENTICATED"
      }
    }
    
    from googleapiclient.discovery import build
    import google.auth
    
    # If modifying these scopes, delete the file token.pickle.
    SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
    
    def main():
    
        creds, project_id = google.auth.default(scopes=SCOPES)
        service = build('gmail', 'v1', credentials=creds)
    
        # Call the Gmail API
        results = service.users().labels().list(userId='me').execute()
        labels = results.get('labels', [])
    
        if not labels:
            print('No labels found.')
        else:
            print('Labels:')
            for label in labels:
                print(label['name'])
    
    if __name__ == '__main__':
        main()
    
    gcloud beta compute instances set-scopes <YOUR_VM_NAME> --zone <YOUR_VM_ZONE> \
    --scopes=https://www.googleapis.com/auth/gmail.readonly,\
    $(gcloud compute instances describe <YOUR_VM_NAME> --zone <YOUR_VM_ZONE> \
    --format json | jq -c ".serviceAccounts[0].scopes" | sed -E "s/\[(.*)\]/\1/g" | sed -E "s/\"//g")