我知道其他人已经发布了类似的问题,但那里的所有提示都没有帮助。我尝试使用 google 帐户和 XOAuth2 通过 SMTP 发送。我在 Windows 上使用 libcurl 7.71.1。
为了获取不记名令牌,我在用户网络浏览器中调用以下 URL:
https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&response_mode=query&prompt=consent&client_id=123456789876-d5pdtc7hl0p1n822cnjh7tf3qbcpqno1.apps.googleusercontent.com&login_hint=mymail%40gmail.com&redirect_uri=http%3A%2F%2Flocalhost%3A8100%2Fmyapp&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.send&state=xsf11765042151615245894
网站打开,身份验证成功后,它会调用我的本地主机端口 8100 并向我发送如下令牌:
GET /myapp?state=xsf11765042151615245894&code=4/1AfJohXmrJc2GD-CGAk7OG7X5o7myvDymYZX-jUJG8s3WKbF63qy8wmt2_ziNTSqU2svQ2g&scope=https://www.googleapis.com/auth/gmail.send HTTP/1.1
注意:我在这篇文章中更改了令牌和 ID,因此我发帖时不会遇到安全问题。
支线任务:在这里,我用大约200个代码回答,但身份验证页面仍在等待什么?
[更新]
现在我使用此代码来编译对令牌 url 的请求,并以 POST 表单的形式发送(出于安全原因更改了值,很遗憾它不能作为 GET 调用使用):
Host: oauth2.googleapis.com
Accept: */*
Content-Length: 765
Content-Type: multipart/form-data
Content-Disposition: form-data;
name="client_secret" GOCSPX-fds5mklfrw8cdnr42cdsc
name="grant_type" authorization_code
name="redirect_uri" http://localhost:8100/myapp
name="code" 4/0AfJohXkgfdcvgSujuj1Wxd8F4QwHipzJ4dcd5LD9mzh9oAw2Hph-Re8j7YoC-OvpxI4Axw
name="client_id" 123456789876-d5pdtc7hl0p1n822cnjh7tf3qbcpqno1.apps.googleusercontent.com
在此之后,我得到一个 json 返回:
{
"access_token": "yt21.a6AfC_btretdfmit59nuvfd8zu9g5novgfdvt3-Qudygl1J2YHnz9EDuN5vxnvH4bKMDAhrrZCQh_cLiTdUbFeljavGH7HLl3nVVET1JrFgGPXL-wP5c6YX9qIjpGA9_narMf-AIkEOO4RDGXJQW4gJ_b9aCgYKAZESARESFQGOcNnCqOhXBKQK3Op-eEoN_pLqiQ0171",
"expires_in": 3599,
"refresh_token": "1//09MmzKo6J7xxFCfgdsmkt543mkvcxjgt4F-vfdimof542jucofdnuvifwe_VTD4bzu3176txgswzub-Zsqlvn9M15XCCuzO3GKfw",
"scope": "https://www.googleapis.com/auth/gmail.send",
"token_type": "Bearer"
}
现在我使用access_token作为承载。
[/更新]
然后我将值提交给 libcurl,如下所示:
sbBearerToken = "yt21.a6AfC_btretdfmit59nuvfd8zu9g5novgfdvt3-Qudygl1J2YHnz9EDuN5vxnvH4bKMDAhrrZCQh_cLiTdUbFeljavGH7HLl3nVVET1JrFgGPXL-wP5c6YX9qIjpGA9_narMf-AIkEOO4RDGXJQW4gJ_b9aCgYKAZESARESFQGOcNnCqOhXBKQK3Op-eEoN_pLqiQ0171" // extracted from above call result json
curl_easy_setopt(curl_Handle, #CURLOPT_USE_SSL, #CURLUSESSL_ALL)
curl_easy_setopt(curl_Handle, #CURLOPT_USERNAME, @sbSMTPUsername)
curl_easy_setopt(curl_Handle, #CURLOPT_HTTPAUTH, #CURLAUTH_BEARER)
curl_easy_setopt(curl_Handle, #CURLOPT_XOAUTH2_BEARER, @sbBearerToken)
这就是curl所做的:
(...)
CURL: STARTTLS
CURL: 220 2.0.0 Ready to start TLS
CURL: EHLO DESKTOP-LKLNJ7V
CURL: 250-smtp.gmail.com at your service, [62.26.97.31]
CURL: 250-SIZE 35882577
CURL: 250-8BITMIME
CURL: 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
CURL: 250-ENHANCEDSTATUSCODES
CURL: 250-PIPELINING
CURL: 250-CHUNKING
CURL: 250 SMTPUTF8
CURL: AUTH XOAUTH2 dXNlc....iRjYzcXk
CURL: 334 eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUiOiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==
CURL: Closing connection 0
CURL: schannel: shutting down SSL/TLS connection with smtp.gmail.com port 25
Error performing GET. Curl ec:67
如果我解码334后面的b64编码结果,那就意味着
{"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}
我已经尝试过的:
还有什么可以让我找出它不起作用的原因吗?
代码=4/1AfJohXmrJc2GD-CGAk7OG7X5o7myvDymYZX-jUJG8s3WKbF63qy8wmt2_ziNTSqU2svQ2g
这是授权码而不是访问令牌。
您需要将授权码换成访问令牌。
POST https://accounts.google.com/o/oauth2/token
code=[CODE]&client_id=[ClientId]&redirect_uri=[redirectURI]&grant_type=authorization_code
对于任何其他遇到同样问题的人,这就是我解决它的方法:
首先我遵循了指南并仅使用发送范围:
https://www.googleapis.com/auth/gmail.send
这不起作用!
在我将范围设置为
后,它立即起作用