为了在我们的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_PATH
指向该服务的已下载凭据文件。 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}')
我感到有些根本的东西我不了解。