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