You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Google XOAuth2通过SMTP发邮件遇400权限范围错误求助

使用libcurl 7.71.1通过XOAuth2发送Gmail邮件时的400错误排查

问题描述

在Windows系统下使用libcurl 7.71.1,尝试通过Google账号及XOAuth2协议实现SMTP邮件发送,收到错误响应:

{"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}

令牌获取流程

  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
  1. 认证成功后本地服务收到授权码:
GET /myapp?state=xsf11765042151615245894&code=4/1AfJohXmrJc2GD-CGAk7OG7X5o7myvDymYZX-jUJG8s3WKbF63qy8wmt2_ziNTSqU2svQ2g&scope=https://www.googleapis.com/auth/gmail.send HTTP/1.1
  1. 通过POST请求获取令牌:
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Accept: */*
Content-Length: 765
Content-Type: multipart/form-data

Content-Disposition: form-data; name="client_secret"
GOCSPX-fds5mklfrw8cdnr42cdsc

Content-Disposition: form-data; name="grant_type"
authorization_code

Content-Disposition: form-data; name="redirect_uri"
http://localhost:8100/myapp

Content-Disposition: form-data; name="code"
4/0AfJohXkgfdcvgSujuj1Wxd8F4QwHipzJ4dcd5LD9mzh9oAw2Hph-Re8j7YoC-OvpxI4Axw

Content-Disposition: form-data; name="client_id"
123456789876-d5pdtc7hl0p1n822cnjh7tf3qbcpqno1.apps.googleusercontent.com

获取到的令牌响应:

{
"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"
}

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: 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

Base64解码334响应内容:

{"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}

已尝试的解决方案

  • 修改权限范围为https://mail.google.com/,或同时包含https://www.googleapis.com/auth/gmail.send与https://mail.google.com/
  • 开启Gmail账号的IMAP功能
  • 在Google开发者控制台将该账号设为OAuth测试用户

进一步排查方向

  • 检查libcurl认证参数的正确性:Gmail SMTP支持OAUTHBEARER认证方式,尝试将CURLOPT_HTTPAUTH设为CURLAUTH_OAUTHBEARER,并使用CURLOPT_OAUTHBEARER传递令牌,而非CURLOPT_XOAUTH2_BEARER,部分libcurl版本对两种参数的处理存在差异。
  • 确认令牌的实际权限范围:修改scope后需重新获取授权码和令牌,旧令牌的scope不会自动更新。可通过JWT解码工具解析access_token,查看其payload中的scope字段是否包含https://mail.google.com/。
  • 更换SMTP端口:当前使用的25端口可能被ISP或Google限制,建议切换到Gmail推荐的587(STARTTLS)或465(SSL直接连接)端口测试。
  • 验证令牌有效性:使用命令行直接测试令牌是否能访问Gmail API,例如:
    curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://gmail.googleapis.com/gmail/v1/users/me/messages/send
    
    根据返回结果判断令牌是否有效、权限是否足够。
  • 调整令牌请求的Content-Type:Google OAuth令牌接口推荐使用application/x-www-form-urlencoded格式,而非multipart/form-data。将POST请求的Content-Type修改为前者,参数以key=value&key2=value2的形式传递,重新获取令牌后测试。
  • 检查libcurl版本兼容性:libcurl 7.71.1可能存在XOAuth2 SMTP认证的已知bug,尝试升级到较新版本(如7.80+),或查阅该版本的发行文档确认是否有相关问题。
  • 排查账号安全设置:确认账号是否开启两步验证(若开启,XOAuth2仍可正常使用,但需确保授权流程正确);检查Google账号的安全中心是否有拦截该应用访问的记录,如有需手动允许。

内容的提问来源于stack exchange,提问作者Volker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:05:55