joh*_*arr 6 linux gmail mutt msmtp oauth2
两年来,我一直很高兴通过 访问我的 Gmail 帐户neomutt
。
我使用“两步验证”应用程序密码(使用应用程序密码登录neomutt
)在本地和我的在线 Gmail 帐户之间进行同步。mbsync
使用 发送 Gmailneomutt
比较棘手,因为msmtp
需要来自Gmail API
. 幸运的是,GitHub 用户 tenllado 提供了我能找到的唯一可行的开源解决方案,他的脚本oauth2token。我将其改编为oauth2tool.sh。其运行步骤如下:
xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
xxxxxxxxxxxxxxxxxxxxxxxx
oauth2.py
(代码“刷新令牌无限期持续”)。$ python2 oauth2.py --user=my@gmail.com --client_id=<myCI> --client_secret=<myCS> --generate_oauth2_token
并按照说明进行操作。它看起来像这样:
1//03xxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxx
account my
auth oauthbearer
host smtp.gmail.com
port 587
from my@gmail.com
user my@gmail.com
passwordeval bash oauth2tool.sh my
Run Code Online (Sandbox Code Playgroud)
然后,当我发送电子邮件时echo "test" | msmtp -a my <target_email>
,我oauth2tool.sh
会提取一个有效的令牌。它执行此操作的方式是,pass
如果令牌未过期,则使用 获取令牌,否则使用 获取新令牌python2 oauth2.py --user=my@gmail.com --client_id=<myCI> --client_secret=<myCS> --refresh_token=<myRT>
。
有了这一切,到目前为止,我可以轻松地通过命令行从我的 Gmail 帐户发送电子邮件。
现在,我曾经不朽的刷新令牌即将过期,我无法续订它们,因为 Gmailoauth2.py
正在使用redirect_uri = urn:ietf:wg:oauth:2.0:oob
,它已被弃用。
通过使用更安全的 OAuth 流,使 Google OAuth 交互更安全“OAuth
带外 (oob) 流将被弃用”。
适用于移动和桌面应用程序的 OAuth 2.0 “环回 IP 地址(macOS、Linux、Windows 桌面)”似乎是前进的方向,但我需要几周的空闲时间(我没有)来弄清楚如何。有什么想法吗?
getmail6已经用他们的脚本getmail-gmail-xoauth-tokensGmail
在一定程度上解决了这个问题,尽管有一个巨大的警告,现在将刷新令牌限制为仅 1 小时,所以下面描述的最后一步,涉及简短的浏览器交互和生成 Google 安全警报需要定期重复,因此这使得该解决方案几乎没有实际价值。(getmailrc-examples确实警告过这一点 - “不幸的是......需要定期重复。”)在发现这一点时,我成功地完成了 Akkana Peck\ 的说明,使用 OAuth2 通过 Gmail 发送邮件(2022 版)(按照建议)在@GuenterRoeck 的评论中)。Microsoft Office 365
Python
Gmail API
(注意:这可能不是唯一或最佳路径,但它有效。在 2020 年,我通过 OP 中描述的现在已过时的路线更轻松地获得了这些凭据,并且它们仍然有效。)
\nProject name
- 我选择了getmail6
。Enabled APIs and services
并单击+ ENABLE APIS AND SERVICES
。ENABLE
选择它。+ CREATE CREDENTIALS
创建OAuth 客户端 ID” ,单击“Configure consent screen
创建 OAuth 客户端 ID”,似乎我们现在需要像应用程序创建者一样继续,这在我看来很荒谬,但没有选择。由于不是 Google Workspace 用户,我不得不选择External
(“适用于任何拥有 Google 帐户的测试用户。您的应用将以测试模式启动,并且仅适用于您添加到测试用户列表中的用户。一旦您的应用已准备好投入生产,您可能需要验证您的应用程序。”)。然后我们有义务指定我们的假想App name
- 我选择了“msmtpGmail”,而我们的User support email
,这是您正在执行所有操作的帐户的帐户,对于我们的 来说也是如此Developer contact information
。然后Save and continue
。Application type
我选择了Desktop app
,并且Name
- 我选择了“msmtp”,最终,我得到了我的Client ID
和Client Secret
。我将它们下载为client_secret_nnnnnnnnnnnn-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com.json
,并将其安全归档。Test users
(因为 Google 没有为您执行此操作)。在这里,我们利用了getmail6的一些辛苦工作。您将需要他们的getmail-gmail-xoauth-tokens Python
脚本。
按照 getmail6\'s getmailrc-examples中的说明(- 搜索“mail.google.com”),制作此 JSON - 我将其命名为我的getmail6.json
:
{"scope": "https://mail.google.com/",\n"user": "yours@gmail.com",\n"client_id": "yours",\n"client_secret": "yours",\n"token_uri": "https://accounts.google.com/o/oauth2/token",\n"auth_uri": "https://accounts.google.com/o/oauth2/auth",\n"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs"}\n
Run Code Online (Sandbox Code Playgroud)\n- 填写yours
...
python3 getmail-gmail-xoauth-tokens --init your.json
(填写your
)>“Google尚未\xe2\x80\x99t验证了此应用程序”> Continue
>“<yourApp>
想要访问您的Google帐户”> Continue
,将其附加到your.json
以下行中:
"access_token": "<extremely_long_key>",\n"expires_at": <now+3600s>,\n"refresh_token": "<another_extremely_long_key>"}\n
Run Code Online (Sandbox Code Playgroud)\n- 这就是我们一直在寻找的,但是 1 小时的过期时间实在是太尴尬了……
\n再次利用getmail-gmail-xoauth-tokens:
\ntls on\ntls_trust_file /etc/ssl/certs/ca-certificates.crt\nlogfile ~/.msmtp.log\naccount your\nauth oauthbearer\nhost smtp.gmail.com\nport 587\nfrom your@gmail.com\nuser your@gmail.com\npasswordeval python3 getmail-gmail-xoauth-tokens your.json\n
Run Code Online (Sandbox Code Playgroud)\n- 填写 的实例your
。
很快,您的刷新令牌就会过时(更改your
),还有一个小时的时间:
tls on\ntls_trust_file /etc/ssl/certs/ca-certificates.crt\nlogfile ~/.msmtp.log\naccount your\nauth oauthbearer\nhost smtp.gmail.com\nport 587\nfrom your@gmail.com\nuser your@gmail.com\npasswordeval python3 getmail-gmail-xoauth-tokens your.json\n
Run Code Online (Sandbox Code Playgroud)\n