Python - 如何在没有用户输入的情况下进行GmailAPI身份验证

3
我有一个小的Python脚本,它收集一些数据并使用Gmail API将其发送到电子邮件中。我的目标是将此脚本放在我的树莓派上,创建一个每日cronjob来调用它,并忘记它。然而,我进行谷歌身份验证的方式阻止了我自动化它。目前,我必须使用浏览器进行身份验证(用户需要按下允许按钮),然后我可以使用凭据几天,然后它们会过期,需要再次输入用户。如何使其仅验证一次,然后开始自动刷新其凭据?
当前代码:
def get_creds():
    creds = None
    if os.path.exists(os.path.join(dir,'token.json')):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)

    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            print("refreshing")
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                os.path.join(dir,'credentials.json'), SCOPES)
            creds = flow.run_local_server(port=0)

        with open(os.path.join(dir,'token.json'), 'w') as token:
            token.write(creds.to_json())

    return creds

1
我最近回答过类似的问题。解决方案是使用刷新令牌,你的代码示例中已经有了,但为了防止令牌过期,你需要发布项目或将其设置为内部。参见避免认证令牌过期 - Daniel
如果您是Google Workspace用户,您只能将项目设置为内部。"因为您不是Google Workspace用户,所以只能将您的应用程序提供给外部(普通用户)使用者。" - machaniv
2个回答

1
您可以使用服务账号代替令牌。它不会过期。
from google.oauth2 import service_account
from googleapiclient.discovery import build

credentials = service_account.Credentials.from_service_account_file(
    CREDENTIALS_JSON_PATH,
    SCOPES
)

service = build('gmail', 'v1', credentials=credentials)

print(service.users().getProfile(userId='me').execute())

如果您创建了Google Workspace服务帐户,则需要指定用户电子邮件地址。
credentials = credentials.with_subject(USER_EMAIL)

0

正如丹尼尔所述,问题在于我的Google云应用程序处于测试模式。我必须先发布它,然后它开始成功地刷新令牌,而无需我的帮助。

避免身份验证令牌过期


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接