本文档定义了与 IMAP AUTHENTICATE
、POP AUTH
和 SMTP AUTH
命令搭配使用的 SASL XOAUTH2 机制。此机制允许使用 OAuth 2.0 访问令牌对用户的 Gmail 帐号进行身份验证。
使用 OAuth 2.0
首先熟悉使用 OAuth 2.0 访问 Google API。该文档说明了 OAuth 2.0 的工作原理以及编写客户端所需执行的步骤。
您可能还需要浏览 XOAUTH2 代码示例,以查看工作示例。
OAuth 2.0 范围
IMAP、POP 和 SMTP 访问的范围为 https://mail.google.com/
。如果您请求访问 IMAP、POP 或 SMTP 应用的完整邮件范围,则必须符合我们的 Google API 服务:用户数据政策。
- 若要获得批准,您的应用必须显示充分利用
https://mail.google.com/
。 - 如果您的应用不需要
https://mail.google.com/
,请迁移到 Gmail API 并使用更精细的受限范围。
Google Workspace的全网域授权
如果您打算使用Google Workspace 全网域授权(通过服务帐号)通过 IMAP 访问 Google Workspace 用户的邮箱,可以改为使用 https://www.googleapis.com/auth/gmail.imap_admin
范围向客户端授权。
使用此范围授权时,IMAP 连接的行为会有所不同:
- 所有标签均通过 IMAP 显示,即使用户在 Gmail 设置中为标签停用了“在 IMAP 中显示”也是如此。
- 无论用户在 Gmail 设置的“文件夹大小限制”中设置了何种设置,所有邮件都会通过 IMAP 显示。
SASL XOAUTH2 机制
XOAUTH2 机制允许客户端向服务器发送 OAuth 2.0 访问令牌。该协议使用经过编码的值,如以下部分中所示。
初始客户响应
SASL XOAUTH2 初始客户端响应采用以下格式:
base64("user=" {User} "^Aauth=Bearer " {Access Token} "^A^A")
使用 RFC 4648 中定义的 base64 编码机制。^A
表示 Control+A (\001)。
例如,在 base64 编码之前,初始客户端响应可能如下所示:
user=someuser@example.com^Aauth=Bearer ya29.vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg^A^A
在 base64 编码后,以下代码变为(为清楚起见,插入了换行符):
dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52
YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0Q2cBAQ==
错误响应
如果初始客户端响应引发错误,则服务器会发送一条质询,其中包含以下格式的错误消息:
base64({JSON-Body})
JSON-Body 包含三个值:status
、schemes
和 scope
。例如:
eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb3BlIjoiaHR0cHM6Ly9t
YWlsLmdvb2dsZS5jb20vIn0K
在 base64 解码后,以下代码变为(为清楚起见,已设置格式):
{
"status":"401",
"schemes":"bearer",
"scope":"https://mail.google.com/"
}
SASL 协议要求客户端对此质询发送空响应。
IMAP 协议交换
本部分介绍了如何将 SASL XOAUTH2 与 Gmail IMAP 服务器搭配使用。
初始客户响应
要通过 SASL XOAUTH2 机制登录,客户端需要使用 XOAUTH2
机制参数以及上述构建的初始客户端响应来调用 AUTHENTICATE
命令。例如:
[connection begins]
C: C01 CAPABILITY
S: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA XLIST
CHILDREN XYZZY SASL-IR AUTH=XOAUTH2 AUTH=XOAUTH
S: C01 OK Completed
C: A01 AUTHENTICATE XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvb
QFhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG
1semRHRXVZMjl0Q2cBAQ==
S: A01 OK Success
[connection continues...]
IMAP 协议交换的注意事项:
- RFC 3501 中介绍了 IMAP
AUTHENTICATE
命令。 - SASL-IR 功能允许在
AUTHENTICATE
命令的第一行中发送初始客户端响应,因此身份验证时只需要一次往返。RFC 4959 中介绍了 SASL-IR。 - AUTH=XOAUTH2 功能声明服务器支持此文档定义的 SASL 机制,并且该机制是通过将 XOAUTH2 指定为
AUTHENTICATE
命令的第一个参数来激活。 AUTHENTICATE
和CAPABILITY
命令中的换行符是为了清晰起见,并不会出现在实际的命令数据中。整个 base64 参数应该是一个没有嵌入空格的连续字符串,以便整个AUTHENTICATE
命令包含一行文本。
错误响应
身份验证失败还会通过 IMAP AUTHENTICATE
命令返回:
[connection begins]
S: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA XLIST
CHILDREN XYZZY SASL-IR AUTH=XOAUTH2
S: C01 OK Completed
C: A01 AUTHENTICATE XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQ
FhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1s
emRHRXVZMjl0Q2cBAQ==
S: + eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb
3BlIjoiaHR0cHM6Ly9tYWlsLmdvb2dsZS5jb20vIn0K
C:
S: A01 NO SASL authentication failed
IMAP 协议交换的注意事项:
- 客户端向包含错误消息的质询发送一个空响应 ("\r\n")。
POP 协议交换
本部分介绍如何将 SASL XOAUTH2 与 Gmail POP 服务器配合使用。
初始客户响应
要通过 SASL XOAUTH2 机制登录,客户端需要使用 XOAUTH2
机制参数以及上述构建的初始客户端响应来调用 AUTH
命令。例如:
[connection begins]
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYX
JlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0
Q2cBAQ==
S: +OK Welcome.
[connection continues...]
POP 协议交换的注意事项:
- RFC 1734 中介绍了 POP
AUTH
命令。 AUTH
命令中的换行符是为了清晰起见,并不会出现在实际的命令数据中。整个 base64 参数应该是一个没有嵌入空格的连续字符串,以便整个AUTH
命令包含一行文本。
错误响应
身份验证失败还会通过 POP AUTH
命令返回:
[connection begins]
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlY
XJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMj
l0Q2cBAQ==
S: + eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUi
OiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==
SMTP 协议交换
本部分介绍了如何将 SASL XOAUTH2 与 Gmail SMTP 服务器搭配使用。
初始客户响应
要使用 XOAUTH2 机制登录,客户端需要使用 XOAUTH2
机制参数和初始客户端响应(如上所述)来调用 AUTH
命令。例如:
[connection begins]
S: 220 mx.google.com ESMTP 12sm2095603fks.9
C: EHLO sender.example.com
S: 250-mx.google.com at your service, [172.31.135.47]
S: 250-SIZE 35651584
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
S: 250-ENHANCEDSTATUSCODES
S: 250 PIPELINING
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlY
XJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMj
l0Q2cBAQ==
S: 235 2.7.0 Accepted
[connection continues...]
关于 SMTP 协议交换的注意事项:
- RFC 4954 中介绍了 SMTP
AUTH
命令。 AUTH
命令中的换行符是为了清晰起见,并不会出现在实际的命令数据中。整个 base64 参数应该是一个没有嵌入空格的连续字符串,以便整个AUTH
命令包含一行文本。
错误响应
身份验证失败也会通过 SMTP AUTH
命令返回:
[connection begins]
S: 220 mx.google.com ESMTP 12sm2095603fks.9
C: EHLO sender.example.com
S: 250-mx.google.com at your service, [172.31.135.47]
S: 250-SIZE 35651584
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
S: 250-ENHANCEDSTATUSCODES
S: 250 PIPELINING
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJl
ciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0Q2cB
AQ==
S: 334 eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb
3BlIjoiaHR0cHM6Ly9tYWlsLmdvb2dsZS5jb20vIn0K
C:
S: 535-5.7.1 Username and Password not accepted. Learn more at
S: 535 5.7.1 https://support.google.com/mail/?p=BadCredentials hx9sm5317360pbc.68
[connection continues...]
关于 SMTP 协议交换的注意事项:
- 客户端向包含错误消息的质询发送一个空响应 ("\r\n")。
参考
- OAUTH2:使用 OAuth 2.0 访问 Google API
- SMTP:RFC 2821:简单邮件传输协议
- IMAP:RFC 3501: 互联网邮件访问协议 - VERSION 4rev1
- POP:RFC 1081:邮局协议 - 版本 3
- SASL:RFC 4422:简单身份验证和安全层 (SASL)
- JSON:RFC 4627:JavaScript 对象表示法的 application/json 媒体类型
- BASE64:RFC 4648:Base16、Base32 和 Base64 数据编码
- SASL-IR:RFC 4959:适用于简单身份验证和安全层 (SASL) 初始客户端响应的 IMAP 扩展
- SMTP-AUTH:RFC 4954:用于身份验证的 SMTP 服务扩展