为邮件客户端添加 OAuth 2.0 代理

2024-10-15

强制使用 OAuth 2.0 认证的邮件提供商越来越多,而一些老客户端并不支持,比如 macOS Catalina 自带的邮件。

于是尝试换 Thunderbird,然而用起来有些……粗犷。

找到一个开源程序 email-oauth2-proxy,它可以建立一个代理,让不支持 OAuth 2.0 的客户端使用 IMAP/POP/SMTP 协议继续访问邮箱,但它的文档写得实在不像给人类看的。

下面以 macOS Catalina 自带邮件客户端添加 Outlook 个人邮箱为例进行说明。

安装

我不需要 GUI,因此直接安装:

$ pipx install emailproxy

配置

建立配置文件 ~/.config/emailproxy.conf

[IMAP-1993]
server_address = outlook.office365.com
server_port = 993
local_address = 127.0.0.1

[SMTP-1587]
server_address = smtp-mail.outlook.com
server_port = 587
server_starttls = True
local_address = 127.0.0.1

[your.address@example.com]
permission_url = https://login.microsoftonline.com/common/oauth2/v2.0/authorize
token_url = https://login.microsoftonline.com/common/oauth2/v2.0/token
oauth2_scope = https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access
redirect_uri = http://localhost
client_id = 9e5f94bc-e8a4-4e73-b8be-63364c29d753

由程序与邮件服务器建立连接,客户端只需以 IMAP/SMTP 等协议访问本地代理,访问本地是不加密的,一般也没必要。

本地端口不能用默认端口(如 993/587),因为默认端口不仅需要以 root 用户运行,客户端也不能添加,否则会提示“服务器拒绝允许通过默认端口进行的连接”。这里用的是 1993/1587。

smtp-mail.outlook.com 是微软用于个人免费账号的 SMTP 服务器,Office 365 账号应该是不一样的,具体自行查找相关文档。SMTP 服务启用了 STARTTLS,因此 server_starttls 设置为 True

your.address@example.com 改为自己的邮箱地址。

client_id 用于模拟某个邮件客户端,这里的 ID 来自 Thunderbird

授权

首次使用必须先登录授权。运行:

$ emailproxy --no-gui --config-file ~/.config/emailproxy.conf --external-auth

典型的流程是:程序将会等待客户端登录,当收到请求时打印一个链接,用浏览器打开并授权,自动跳转到 redirect_uri 开头的链接,回到终端输入跳转后的链接,授权成功。token 默认保存在配置文件中。

由于苹果自带邮箱太简陋,登录时遇到很多麻烦。

首先添加账号时,邮件地址不能写真实地址,否则客户端检测到是微软的域名,就自作聪明建立连接,但这显然不可能成功。可以先写无法解析的地址,例如 a@b,之后进入下一步再修改。

密码可以按自己喜好填写,因为它不是与邮件提供商通信的密码,只是本地代理的密码,程序会自动记住。但再次登录时要保持一致。

发件和收件服务器都填写 localhost。提示错误可以忽略。总之先建立一个账号,才能进入偏好设置进行详细设置。苹果有点过于把用户当傻子了。

在偏好设置中找到添加的账号,点击右侧服务器设置,用户名和密码自行设置,取消勾选“自动管理连接设置”,端口改为 1993,在“高级 IMAP 设置”里勾选“允许不安全认证”。

下方类似地编辑 SMTP 设置,同样将端口改为 1587,并允许不安全认证。

这时终端会输出需要授权的链接,类似于:

$ emailproxy --no-gui --config-file ~/.config/emailproxy.conf --external-auth
2024-10-15 00:00:00: Initialising Email OAuth 2.0 Proxy (version 2024-09-12) from config file /path/to/.config/emailproxy.conf
2024-10-15 00:00:00: Starting IMAP server at 127.0.0.1:1993 (unsecured) proxying outlook.office365.com:993 (SSL/TLS)
2024-10-15 00:00:00: Starting SMTP server at 127.0.0.1:1587 (unsecured) proxying smtp-mail.outlook.com:587 (STARTTLS)
2024-10-15 00:00:00: Initialised Email OAuth 2.0 Proxy - listening for authentication requests. Connect your email client to begin
2024-10-15 00:00:00: Accepting new connection from [::ffff:127.0.0.1]:52602 to IMAP server at 127.0.0.1:1993 (unsecured) proxying outlook.office365.com:993 (SSL/TLS)
2024-10-15 00:00:00: Authorisation request received for your.address@example.com (external auth mode)
2024-10-15 00:00:00: Email OAuth 2.0 Proxy No-GUI external auth mode: please authorise a request for account your.address@example.com
2024-10-15 00:00:00: Please visit the following URL to authenticate account your.address@example.com: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=9e5f94bc-e8a4-4e73-b8be-63364c29d753&redirect_uri=http%3A%2F%2Flocalhost&scope=https%3A%2F%2Foutlook.office.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office.com%2FPOP.AccessAsUser.All%20https%3A%2F%2Foutlook.office.com%2FSMTP.Send%20offline_access&response_type=code&access_type=offline&login_hint=your.address%40example.com

Copy+paste or press [↵ Return] to visit the following URL and authenticate account your.address@example.com: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_i
d=9e5f94bc-e8a4-4e73-b8be-63364c29d753&redirect_uri=http%3A%2F%2Flocalhost&scope=https%3A%2F%2Foutlook.office.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office.com%2FPO
P.AccessAsUser.All%20https%3A%2F%2Foutlook.office.com%2FSMTP.Send%20offline_access&response_type=code&access_type=offline&login_hint=your.address%40example.com then paste here the
full post-authentication URL from the browser's address bar (it should start with http://localhost): 

打开此链接,授权后自动跳转到类似 http://localhost/?code=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 的地址。将此地址复制到终端回车即可授权完成。

至此邮箱登录成功。以后只需要运行 emailproxy --no-gui --config-file ~/.config/emailproxy.conf 即可。

另外需要注意的是,账号的“邮箱行为”中,发件箱建议改为“已发送邮件”,否则发送邮件后,服务器发件箱将存在两份一模一样的邮件。但这样改后,本地发件箱将不会与服务器完全同步,例如删除本地发件箱中的邮件,服务器中仍然存在。

自动启动

新建 ~/Library/LaunchAgents/emailproxy.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>emailproxy</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/bin/emailproxy</string>
		<string>--no-gui</string>
		<string>--config-file</string>
		<string>/path/to/.config/emailproxy.conf</string>
		<string>--log-file</string>
		<string>/usr/local/var/log/emailproxy.log</string>
	</array>
	<key>KeepAlive</key>
	<true/>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>

修改其中配置文件的路径,并加载:

$ launchctl load /path/to/emailproxy.plist
macOS邮件

本作品根据 署名-非商业性使用-相同方式共享 4.0 国际许可 进行授权。

下载官方旧版本 Chrome