You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

仅用用户名和密码能否通过Gmail API发邮件?附报错求助

关于用用户名密码通过Gmail API/SMTP发送邮件的问题

首先明确两个核心点:

  • Gmail API本身完全不支持仅用用户名密码认证:它基于OAuth 2.0协议构建,必须使用客户端ID/密钥、服务账户凭证这类OAuth相关信息来获取访问令牌,不存在直接用用户名密码构建Gmail实例的方式。
  • 你测试的是SMTP协议发邮件(不是Gmail API),但现在Google几乎全面禁用了普通用户名密码的SMTP登录,这就是你遇到AuthenticationFailedException的直接原因。

为什么你的SMTP代码报错?

Google早在几年前就默认关闭了“不太安全的应用”的访问权限,不管是个人账户还是企业Workspace账户,直接用账户原密码通过SMTP登录都会被拒绝,报错里的535-5.7.8就是这个安全限制的提示。

可行的解决办法

1. SMTP方式:改用应用专用密码(仅适用于开启两步验证的账户)

如果你的账户已经开启了两步验证,可以创建一个应用专用密码来替换代码里的普通密码:

  • 个人账户:在Google账户设置的“安全”板块找到“应用专用密码”,生成一个专门用于邮件客户端的密码
  • 企业Workspace账户:需要管理员允许该账户创建应用专用密码,或者在管理控制台开启相关权限

把代码里的password替换成生成的应用专用密码后,原有SMTP代码就能正常工作。

2. 改用Gmail API(推荐,更安全合规)

既然你最初想使用Gmail API,这里给你一个适合企业Workspace账户的服务账户示例(支持域范围授权,无需用户手动授权):

首先要在Google Cloud控制台创建服务账户,下载JSON密钥文件,然后让Workspace管理员给这个服务账户授予Gmail API的域范围权限(比如https://www.googleapis.com/auth/gmail.send)。

然后用Kotlin实现发送邮件:

import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.json.gson.GsonFactory
import com.google.api.services.gmail.Gmail
import com.google.api.services.gmail.GmailScopes
import com.google.api.services.gmail.model.Message
import com.google.auth.http.HttpCredentialsAdapter
import com.google.auth.oauth2.GoogleCredentials
import java.io.ByteArrayOutputStream
import java.io.FileInputStream
import javax.mail.Session
import javax.mail.internet.InternetAddress
import javax.mail.internet.MimeMessage

@Test fun sendMailViaGmailAPI() {
    // 加载服务账户密钥文件
    val credentials = GoogleCredentials.fromStream(FileInputStream("service-account-key.json"))
        .createScoped(listOf(GmailScopes.GMAIL_SEND))
        // 域范围授权,替换为你的企业邮箱账户
        .createDelegated("your-enterprise-account@your-domain.com")

    // 构建Gmail API实例
    val gmail = Gmail.Builder(
        GoogleNetHttpTransport.newTrustedTransport(),
        GsonFactory.getDefaultInstance(),
        HttpCredentialsAdapter(credentials)
    ).setApplicationName("Your App Name").build()

    // 创建MIME格式邮件
    val session = Session.getDefaultInstance(Properties())
    val mimeMessage = MimeMessage(session).apply {
        setFrom(InternetAddress("your-enterprise-account@your-domain.com"))
        setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse("recipient@example.com"))
        subject = "Testing Gmail API"
        setText("Hello from Gmail API!")
    }

    // 转换为Gmail API要求的Message格式
    val baos = ByteArrayOutputStream()
    mimeMessage.writeTo(baos)
    val message = Message().setRaw(
        java.util.Base64.getUrlEncoder().encodeToString(baos.toByteArray())
    )

    // 发送邮件
    gmail.users().messages().send("me", message).execute()
    println("Mail sent successfully via Gmail API!")
}

总结

  • 别再尝试用普通用户名密码调用Gmail API,这是不可能实现的,必须依赖OAuth 2.0相关凭证
  • SMTP方式现在只能通过应用专用密码(需开启两步验证)或OAuth 2.0认证来使用
  • 企业账户优先推荐Gmail API + 服务账户域范围授权的方案,无需用户交互,更适合自动化场景

内容的提问来源于stack exchange,提问作者Glory to Russia

火山引擎 最新活动