我有以下场景:
到目前为止,这适用于应用程序密码(将被关闭)。
我能够为单个用户(使用 Web 登录)创建令牌并登录 imap(ssl),但对于服务帐户,如果没有超级管理员权限,似乎无法“模拟”用户。我发现的所有描述都要求我给予该服务的域名模拟权(我们的 IT 永远不会授予该权利)
所以问题是: 如何在没有用户交互的情况下获取单个 Gmail 收件箱的访问令牌(刷新令牌不够)?
总结到目前为止的解决方案:
转到谷歌云控制台(https://cloud.google.com/console)并创建一个新的应用程序/项目。在“API 和服务”中,您可能需要先激活 gmail api。
您需要配置“OAuth 同意屏幕”。这是第一个障碍。这仅适用于实习生的工作空间环境。否则您只能将其用作外部/测试环境。在测试中,您有一定的限制,主要是您只能使用受邀请的测试帐户,并且所有代币都限制为 7 天。使用gmail api需要征得同意。(我用的是complete,因为我需要移动/删除邮件)
在“凭据”中创建一个新的 OAuth2 客户端 ID(我用于桌面应用程序)。通过收集到的数据,您可以使用任何库(我使用 nimbus,但它可以与 OIDC 的任何其他完整实现一起使用)来创建授权码流。你需要设置
创建后,所有这些数据都显示在凭据屏幕上。例如,如果您选择仅只读访问 (https://www.googleapis.com/auth/gmail.readonly),范围可能会发生变化。这样您就可以执行身份验证代码流程并将获得访问和刷新令牌。
之后,您可以将刷新令牌提供给您的服务。该服务需要执行刷新令牌流(再次使用您最喜欢的 OIDC 库和上述设置)来获取新的访问令牌。如上所述,刷新令牌在测试模式下 7 天后过期。否则它应该(未经测试!)不会过期。然而,每个帐户的刷新令牌是有限制的(据我所知,有 25 个)。如果您超出此范围,最旧的将被停用。
刷新令牌流中的访问令牌(默认情况下)有效期为 1 小时,可用作 imap (ssl) 登录的密码。对于 Java 来说,它看起来像:
Properties props = new Properties();
props.put("mail.imaps.auth.mechanisms", "XOAUTH2");
Session session = Session.getInstance(props);
session.setDebug(true);
IMAPSSLStore store = new IMAPSSLStore(session, null);
store.connect("imap.gmail.com", "[email protected]", accessTokenString);
Folder in = store.getFolder("Inbox");
in.open(2);
System.out.println(in.getMessage(1).getSubject());
请注意:给定的邮件地址必须是您用于创建刷新令牌的地址。对其他人不起作用。
如果您不介意打开工作区中的所有邮箱,您也可以使用服务帐户。这里有一个比较完整的解释:https://www.limilabs.com/blog/oauth2-gmail-imap-service-account
关于测试模式:如果您有一个“普通”gmail 帐户,那么获得非测试模式同意屏幕是非常“麻烦”的。您需要制作 YouTube 视频和大量法律/GDPR 内容...因此这对于测试很有用,但对于部署,您需要一个具有自己域的工作区。
希望这对其他人有帮助;-)