Python GCP身份验证:刷新错误

Python GCP身份验证:刷新错误,python,authentication,google-cloud-platform,gmail,authorization,Python,Authentication,Google Cloud Platform,Gmail,Authorization,为了在我们的GCP后端来回测试邮件发送代码,我向GMail收件箱发送了一封电子邮件,并试图验证邮件是否到达。当前的GMail API认证机制相当标准,从GMail API文档中粘贴,并嵌入到函数中: def authenticate(): """Authenticates to the Gmail API using data in credentials.json, returning the service instance for use in queries etc.""

为了在我们的GCP后端来回测试邮件发送代码,我向GMail收件箱发送了一封电子邮件,并试图验证邮件是否到达。当前的GMail API认证机制相当标准,从GMail API文档中粘贴,并嵌入到函数中:

def authenticate():
    """Authenticates to the Gmail API using data in credentials.json,
    returning the service instance for use in queries etc."""
    store = file.Storage('token.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets(CRED_FILE_PATH, SCOPES)
        creds = tools.run_flow(flow, store)
    service = build('gmail', 'v1', http=creds.authorize(Http()))
    return service
CRED_FILE_路径
指向服务的已下载凭据文件。缺少
token.json
文件会在通过浏览器窗口进行身份验证交互后触发其重新创建,就像令牌过期一样

这是一个必须无头运行的集成测试(即没有任何交互)。当需要重新身份验证时,当身份验证流开始访问
sys.argv
时,测试当前会引发异常,这意味着它会看到
pytest
的参数

我一直试图找到如何使用不需要用户交互的机制(比如API密钥)进行可靠的身份验证。文档或Stackoverflow中似乎没有任何内容可以回答这个问题

最近的一项工作是使用GMail委派服务帐户中的密钥文件来避免交互式Oauth2流

def authenticate():
    """Authenticates to the Gmail API using data in g_suite_access.json,
    returning the service instance for use in queries etc."""
    main_cred = service_account.Credentials.from_service_account_file(
        CRED_FILE_PATH, scopes=SCOPES)
    # Establish limited credential to minimise any damage.
    credentials = main_cred.with_subject(GMAIL_USER)
    service = build('gmail', 'v1', credentials=credentials)
    return service
尝试使用此服务时出错

        response = service.users().messages().list(userId='me',
                                    q=f'subject:{subject}').execute()
我得到:

google.auth.exceptions.RefreshError:
  ('unauthorized_client: Client is unauthorized to retrieve access tokens using this method.',
   '{\n "error": "unauthorized_client",\n "error_description": "Client is unauthorized to retrieve access tokens using this method."\n}')

我感觉有些基本的东西我不明白。

服务帐户需要授权,否则它无法访问域的电子邮件

“客户端无权使用此方法检索访问令牌”

表示您未对其进行适当授权;检查


来源:

为什么您不能使用对gmail帐户的IMAP访问来执行此集成测试?我明白,这不是你想要得到的帮助,但是这似乎更容易实现集成测试的目标。我确实考虑过了,但是由于我们希望以后使用Gmail API服务来实现其他目的,这只会把问题踢下去。讽刺的是,进一步研究IMAP解决方案,我在使用IMAP进行身份验证时遇到了困难,进一步的研究让我找到了答案,答案是。。。要使用OAuth2身份验证!!好吧,这只有在你禁用“访问不太安全的应用”时才行。所以从技术上讲,它不是检查电子邮件是否到达的拦截器——只需要更改此设置以允许。但是,既然你以后需要GMail API,那显然不是一个永久的解决方案,可能只是一个临时的解决办法。不过IMAP完全可以工作——我用它把gmail收件箱的内容移到别处。我试着运行了你的代码,效果非常好。请检查两件事-1。如果您授权的范围正确。2.我通常看到,当服务帐户授权中缺少作用域时会出现此错误。你是否正确地遵循了这个原则?